| ... | ... | @@ -12059,8 +12059,12 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 12059 | 12059 | const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; |
| 12060 | 12060 | const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; |
| 12061 | 12061 | |
| 12062 | | const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs); |
| 12063 | | const rhs_info = try sema.getArrayCatInfo(block, rhs_src, rhs); |
| 12062 | const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs) orelse { |
| 12063 | return sema.fail(block, lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(sema.mod)}); |
| 12064 | }; |
| 12065 | const rhs_info = try sema.getArrayCatInfo(block, rhs_src, rhs) orelse { |
| 12066 | return sema.fail(block, rhs_src, "expected indexable; found '{}'", .{rhs_ty.fmt(sema.mod)}); |
| 12067 | }; |
| 12064 | 12068 | |
| 12065 | 12069 | const resolved_elem_ty = t: { |
| 12066 | 12070 | var trash_block = block.makeSubBlock(); |
| ... | ... | @@ -12220,7 +12224,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 12220 | 12224 | return block.addAggregateInit(result_ty, element_refs); |
| 12221 | 12225 | } |
| 12222 | 12226 | |
| 12223 | | fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref) !Type.ArrayInfo { |
| 12227 | fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref) !?Type.ArrayInfo { |
| 12224 | 12228 | const operand_ty = sema.typeOf(operand); |
| 12225 | 12229 | switch (operand_ty.zigTypeTag()) { |
| 12226 | 12230 | .Array => return operand_ty.arrayInfo(), |
| ... | ... | @@ -12248,7 +12252,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins |
| 12248 | 12252 | }, |
| 12249 | 12253 | else => {}, |
| 12250 | 12254 | } |
| 12251 | | return sema.fail(block, src, "expected indexable; found '{}'", .{operand_ty.fmt(sema.mod)}); |
| 12255 | return null; |
| 12252 | 12256 | } |
| 12253 | 12257 | |
| 12254 | 12258 | fn analyzeTupleMul( |
| ... | ... | @@ -12330,16 +12334,33 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 12330 | 12334 | const lhs_ty = sema.typeOf(lhs); |
| 12331 | 12335 | const src: LazySrcLoc = inst_data.src(); |
| 12332 | 12336 | const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; |
| 12337 | const operator_src: LazySrcLoc = .{ .node_offset_main_token = inst_data.src_node }; |
| 12333 | 12338 | const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; |
| 12334 | 12339 | |
| 12335 | | // In `**` rhs must be comptime-known, but lhs can be runtime-known |
| 12336 | | const factor = try sema.resolveInt(block, rhs_src, extra.rhs, Type.usize, "array multiplication factor must be comptime-known"); |
| 12337 | | |
| 12338 | 12340 | if (lhs_ty.isTuple()) { |
| 12341 | // In `**` rhs must be comptime-known, but lhs can be runtime-known |
| 12342 | const factor = try sema.resolveInt(block, rhs_src, extra.rhs, Type.usize, "array multiplication factor must be comptime-known"); |
| 12339 | 12343 | return sema.analyzeTupleMul(block, inst_data.src_node, lhs, factor); |
| 12340 | 12344 | } |
| 12341 | 12345 | |
| 12342 | | const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs); |
| 12346 | // Analyze the lhs first, to catch the case that someone tried to do exponentiation |
| 12347 | const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs) orelse { |
| 12348 | const msg = msg: { |
| 12349 | const msg = try sema.errMsg(block, lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(sema.mod)}); |
| 12350 | errdefer msg.destroy(sema.gpa); |
| 12351 | switch (lhs_ty.zigTypeTag()) { |
| 12352 | .Int, .Float, .ComptimeFloat, .ComptimeInt, .Vector => { |
| 12353 | try sema.errNote(block, operator_src, msg, "this operator multiplies arrays; use std.math.pow for exponentiation", .{}); |
| 12354 | }, |
| 12355 | else => {}, |
| 12356 | } |
| 12357 | break :msg msg; |
| 12358 | }; |
| 12359 | return sema.failWithOwnedErrorMsg(msg); |
| 12360 | }; |
| 12361 | |
| 12362 | // In `**` rhs must be comptime-known, but lhs can be runtime-known |
| 12363 | const factor = try sema.resolveInt(block, rhs_src, extra.rhs, Type.usize, "array multiplication factor must be comptime-known"); |
| 12343 | 12364 | |
| 12344 | 12365 | const result_len_u64 = std.math.mul(u64, lhs_info.len, factor) catch |
| 12345 | 12366 | return sema.fail(block, rhs_src, "operation results in overflow", .{}); |