| author | |
| committer | |
| log | a2793f8ab831b4a9ffba24540e40a862f32b9d90 |
| tree | a2f8a128ca8445ef19f3ad5061ca7c53ae2936ad |
| parent | 2c639d657002ac66749d08c4977cbb201d113ce1 |
| parent | 0606f0aa5576122204886f1a3c9530c0ce75c044 |
| signature |
Vector type resolution/coercion fixes2 files changed, 77 insertions(+), 0 deletions(-)
src/Sema.zig+39| ... | ... | @@ -2599,6 +2599,20 @@ fn coerceResultPtr( |
| 2599 | 2599 | const trash_inst = trash_block.instructions.pop(); |
| 2600 | 2600 | |
| 2601 | 2601 | switch (air_tags[trash_inst]) { |
| 2602 | // Array coerced to Vector where element size is not equal but coercible. | |
| 2603 | .aggregate_init => { | |
| 2604 | const ty_pl = air_datas[trash_inst].ty_pl; | |
| 2605 | const ptr_operand_ty = try Type.ptr(sema.arena, sema.mod, .{ | |
| 2606 | .pointee_type = try sema.analyzeAsType(block, src, ty_pl.ty), | |
| 2607 | .@"addrspace" = addr_space, | |
| 2608 | }); | |
| 2609 | ||
| 2610 | if (try sema.resolveDefinedValue(block, src, new_ptr)) |ptr_val| { | |
| 2611 | return sema.addConstant(ptr_operand_ty, ptr_val); | |
| 2612 | } else { | |
| 2613 | return sema.bitCast(block, ptr_operand_ty, new_ptr, src, null); | |
| 2614 | } | |
| 2615 | }, | |
| 2602 | 2616 | .bitcast => { |
| 2603 | 2617 | const ty_op = air_datas[trash_inst].ty_op; |
| 2604 | 2618 | const operand_ty = sema.typeOf(ty_op.operand); |
| ... | ... | @@ -30068,6 +30082,31 @@ fn resolvePeerTypes( |
| 30068 | 30082 | continue; |
| 30069 | 30083 | }, |
| 30070 | 30084 | .Vector => switch (chosen_ty_tag) { |
| 30085 | .Vector => { | |
| 30086 | const chosen_len = chosen_ty.vectorLen(); | |
| 30087 | const candidate_len = candidate_ty.vectorLen(); | |
| 30088 | if (chosen_len != candidate_len) | |
| 30089 | continue; | |
| 30090 | ||
| 30091 | const chosen_child_ty = chosen_ty.childType(); | |
| 30092 | const candidate_child_ty = candidate_ty.childType(); | |
| 30093 | if (chosen_child_ty.zigTypeTag() == .Int and candidate_child_ty.zigTypeTag() == .Int) { | |
| 30094 | const chosen_info = chosen_child_ty.intInfo(target); | |
| 30095 | const candidate_info = candidate_child_ty.intInfo(target); | |
| 30096 | if (chosen_info.bits < candidate_info.bits) { | |
| 30097 | chosen = candidate; | |
| 30098 | chosen_i = candidate_i + 1; | |
| 30099 | } | |
| 30100 | continue; | |
| 30101 | } | |
| 30102 | if (chosen_child_ty.zigTypeTag() == .Float and candidate_child_ty.zigTypeTag() == .Float) { | |
| 30103 | if (chosen_ty.floatBits(target) < candidate_ty.floatBits(target)) { | |
| 30104 | chosen = candidate; | |
| 30105 | chosen_i = candidate_i + 1; | |
| 30106 | } | |
| 30107 | continue; | |
| 30108 | } | |
| 30109 | }, | |
| 30071 | 30110 | .Array => { |
| 30072 | 30111 | chosen = candidate; |
| 30073 | 30112 | chosen_i = candidate_i + 1; |
test/behavior/vector.zig+38| ... | ... | @@ -175,6 +175,44 @@ test "array to vector" { |
| 175 | 175 | comptime try S.doTheTest(); |
| 176 | 176 | } |
| 177 | 177 | |
| 178 | test "array to vector with element type coercion" { | |
| 179 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | |
| 180 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | |
| 181 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | |
| 182 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | |
| 183 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | |
| 184 | ||
| 185 | const S = struct { | |
| 186 | fn doTheTest() !void { | |
| 187 | var foo: f16 = 3.14; | |
| 188 | var arr32 = [4]f32{ foo, 1.5, 0.0, 0.0 }; | |
| 189 | var vec: @Vector(4, f32) = [4]f16{ foo, 1.5, 0.0, 0.0 }; | |
| 190 | try std.testing.expect(std.mem.eql(f32, &@as([4]f32, vec), &arr32)); | |
| 191 | } | |
| 192 | }; | |
| 193 | try S.doTheTest(); | |
| 194 | comptime try S.doTheTest(); | |
| 195 | } | |
| 196 | ||
| 197 | test "peer type resolution with coercible element types" { | |
| 198 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | |
| 199 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | |
| 200 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | |
| 201 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | |
| 202 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | |
| 203 | ||
| 204 | const S = struct { | |
| 205 | fn doTheTest() !void { | |
| 206 | var b: @Vector(2, u8) = .{ 1, 2 }; | |
| 207 | var a: @Vector(2, u16) = .{ 2, 1 }; | |
| 208 | var t: bool = true; | |
| 209 | var c = if (t) a else b; | |
| 210 | try std.testing.expect(@TypeOf(c) == @Vector(2, u16)); | |
| 211 | } | |
| 212 | }; | |
| 213 | comptime try S.doTheTest(); | |
| 214 | } | |
| 215 | ||
| 178 | 216 | test "tuple to vector" { |
| 179 | 217 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 180 | 218 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |