| ... | ... | @@ -768,7 +768,7 @@ fn analyzeBodyInner( |
| 768 | 768 | .optional_type => try sema.zirOptionalType(block, inst), |
| 769 | 769 | .param_type => try sema.zirParamType(block, inst), |
| 770 | 770 | .ptr_type => try sema.zirPtrType(block, inst), |
| 771 | | .ptr_type_simple => try sema.zirPtrTypeSimple(block, inst), |
| 771 | .overflow_arithmetic_ptr => try sema.zirOverflowArithmeticPtr(block, inst), |
| 772 | 772 | .ref => try sema.zirRef(block, inst), |
| 773 | 773 | .ret_err_value_code => try sema.zirRetErrValueCode(inst), |
| 774 | 774 | .shr => try sema.zirShr(block, inst, .shr), |
| ... | ... | @@ -892,7 +892,7 @@ fn analyzeBodyInner( |
| 892 | 892 | .shl_sat => try sema.zirShl(block, inst, .shl_sat), |
| 893 | 893 | |
| 894 | 894 | .ret_ptr => try sema.zirRetPtr(block, inst), |
| 895 | | .ret_type => try sema.zirRetType(block, inst), |
| 895 | .ret_type => try sema.addType(sema.fn_ret_ty), |
| 896 | 896 | |
| 897 | 897 | // Instructions that we know to *always* be noreturn based solely on their tag. |
| 898 | 898 | // These functions match the return type of analyzeBody so that we can |
| ... | ... | @@ -1173,7 +1173,7 @@ fn analyzeBodyInner( |
| 1173 | 1173 | } else { |
| 1174 | 1174 | const src_node = sema.code.instructions.items(.data)[inst].node; |
| 1175 | 1175 | const src = LazySrcLoc.nodeOffset(src_node); |
| 1176 | | try sema.requireRuntimeBlock(block, src); |
| 1176 | try sema.requireFunctionBlock(block, src); |
| 1177 | 1177 | break always_noreturn; |
| 1178 | 1178 | } |
| 1179 | 1179 | }, |
| ... | ... | @@ -1303,7 +1303,7 @@ fn analyzeBodyInner( |
| 1303 | 1303 | const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index); |
| 1304 | 1304 | const then_body = sema.code.extra[extra.end..][0..extra.data.then_body_len]; |
| 1305 | 1305 | const else_body = sema.code.extra[extra.end + then_body.len ..][0..extra.data.else_body_len]; |
| 1306 | | const cond = try sema.resolveInstConst(block, cond_src, extra.data.condition); |
| 1306 | const cond = try sema.resolveInstConst(block, cond_src, extra.data.condition, "condition in comptime branch must be comptime known"); |
| 1307 | 1307 | const inline_body = if (cond.val.toBool()) then_body else else_body; |
| 1308 | 1308 | const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse |
| 1309 | 1309 | break always_noreturn; |
| ... | ... | @@ -1319,7 +1319,7 @@ fn analyzeBodyInner( |
| 1319 | 1319 | const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index); |
| 1320 | 1320 | const then_body = sema.code.extra[extra.end..][0..extra.data.then_body_len]; |
| 1321 | 1321 | const else_body = sema.code.extra[extra.end + then_body.len ..][0..extra.data.else_body_len]; |
| 1322 | | const cond = try sema.resolveInstConst(block, cond_src, extra.data.condition); |
| 1322 | const cond = try sema.resolveInstConst(block, cond_src, extra.data.condition, "condition in comptime branch must be comptime known"); |
| 1323 | 1323 | const inline_body = if (cond.val.toBool()) then_body else else_body; |
| 1324 | 1324 | const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse |
| 1325 | 1325 | break always_noreturn; |
| ... | ... | @@ -1339,7 +1339,7 @@ fn analyzeBodyInner( |
| 1339 | 1339 | const err_union = try sema.resolveInst(extra.data.operand); |
| 1340 | 1340 | const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union); |
| 1341 | 1341 | assert(is_non_err != .none); |
| 1342 | | const is_non_err_tv = try sema.resolveInstConst(block, operand_src, is_non_err); |
| 1342 | const is_non_err_tv = try sema.resolveInstConst(block, operand_src, is_non_err, "try operand inside comptime block must be comptime known"); |
| 1343 | 1343 | if (is_non_err_tv.val.toBool()) { |
| 1344 | 1344 | const err_union_ty = sema.typeOf(err_union); |
| 1345 | 1345 | break :blk try sema.analyzeErrUnionPayload(block, src, err_union_ty, err_union, operand_src, false); |
| ... | ... | @@ -1395,7 +1395,7 @@ fn analyzeBodyInner( |
| 1395 | 1395 | const err_union = try sema.analyzeLoad(block, src, operand, operand_src); |
| 1396 | 1396 | const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union); |
| 1397 | 1397 | assert(is_non_err != .none); |
| 1398 | | const is_non_err_tv = try sema.resolveInstConst(block, operand_src, is_non_err); |
| 1398 | const is_non_err_tv = try sema.resolveInstConst(block, operand_src, is_non_err, "try operand inside comptime block must be comptime known"); |
| 1399 | 1399 | if (is_non_err_tv.val.toBool()) { |
| 1400 | 1400 | break :blk try sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false); |
| 1401 | 1401 | } |
| ... | ... | @@ -1478,11 +1478,12 @@ fn resolveConstBool( |
| 1478 | 1478 | block: *Block, |
| 1479 | 1479 | src: LazySrcLoc, |
| 1480 | 1480 | zir_ref: Zir.Inst.Ref, |
| 1481 | reason: []const u8, |
| 1481 | 1482 | ) !bool { |
| 1482 | 1483 | const air_inst = try sema.resolveInst(zir_ref); |
| 1483 | 1484 | const wanted_type = Type.bool; |
| 1484 | 1485 | const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src); |
| 1485 | | const val = try sema.resolveConstValue(block, src, coerced_inst); |
| 1486 | const val = try sema.resolveConstValue(block, src, coerced_inst, reason); |
| 1486 | 1487 | return val.toBool(); |
| 1487 | 1488 | } |
| 1488 | 1489 | |
| ... | ... | @@ -1491,11 +1492,12 @@ pub fn resolveConstString( |
| 1491 | 1492 | block: *Block, |
| 1492 | 1493 | src: LazySrcLoc, |
| 1493 | 1494 | zir_ref: Zir.Inst.Ref, |
| 1495 | reason: []const u8, |
| 1494 | 1496 | ) ![]u8 { |
| 1495 | 1497 | const air_inst = try sema.resolveInst(zir_ref); |
| 1496 | 1498 | const wanted_type = Type.initTag(.const_slice_u8); |
| 1497 | 1499 | const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src); |
| 1498 | | const val = try sema.resolveConstValue(block, src, coerced_inst); |
| 1500 | const val = try sema.resolveConstValue(block, src, coerced_inst, reason); |
| 1499 | 1501 | return val.toAllocatedBytes(wanted_type, sema.arena, sema.mod); |
| 1500 | 1502 | } |
| 1501 | 1503 | |
| ... | ... | @@ -1514,7 +1516,7 @@ fn analyzeAsType( |
| 1514 | 1516 | ) !Type { |
| 1515 | 1517 | const wanted_type = Type.initTag(.@"type"); |
| 1516 | 1518 | const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src); |
| 1517 | | const val = try sema.resolveConstValue(block, src, coerced_inst); |
| 1519 | const val = try sema.resolveConstValue(block, src, coerced_inst, "types must be comptime known"); |
| 1518 | 1520 | var buffer: Value.ToTypeBuffer = undefined; |
| 1519 | 1521 | const ty = val.toType(&buffer); |
| 1520 | 1522 | return ty.copy(sema.arena); |
| ... | ... | @@ -1567,12 +1569,13 @@ fn resolveValue( |
| 1567 | 1569 | block: *Block, |
| 1568 | 1570 | src: LazySrcLoc, |
| 1569 | 1571 | air_ref: Air.Inst.Ref, |
| 1572 | reason: []const u8, |
| 1570 | 1573 | ) CompileError!Value { |
| 1571 | 1574 | if (try sema.resolveMaybeUndefValAllowVariables(block, src, air_ref)) |val| { |
| 1572 | 1575 | if (val.tag() == .generic_poison) return error.GenericPoison; |
| 1573 | 1576 | return val; |
| 1574 | 1577 | } |
| 1575 | | return sema.failWithNeededComptime(block, src); |
| 1578 | return sema.failWithNeededComptime(block, src, reason); |
| 1576 | 1579 | } |
| 1577 | 1580 | |
| 1578 | 1581 | /// Value Tag `variable` will cause a compile error. |
| ... | ... | @@ -1582,15 +1585,16 @@ fn resolveConstMaybeUndefVal( |
| 1582 | 1585 | block: *Block, |
| 1583 | 1586 | src: LazySrcLoc, |
| 1584 | 1587 | inst: Air.Inst.Ref, |
| 1588 | reason: []const u8, |
| 1585 | 1589 | ) CompileError!Value { |
| 1586 | 1590 | if (try sema.resolveMaybeUndefValAllowVariables(block, src, inst)) |val| { |
| 1587 | 1591 | switch (val.tag()) { |
| 1588 | | .variable => return sema.failWithNeededComptime(block, src), |
| 1592 | .variable => return sema.failWithNeededComptime(block, src, reason), |
| 1589 | 1593 | .generic_poison => return error.GenericPoison, |
| 1590 | 1594 | else => return val, |
| 1591 | 1595 | } |
| 1592 | 1596 | } |
| 1593 | | return sema.failWithNeededComptime(block, src); |
| 1597 | return sema.failWithNeededComptime(block, src, reason); |
| 1594 | 1598 | } |
| 1595 | 1599 | |
| 1596 | 1600 | /// Will not return Value Tags: `variable`, `undef`. Instead they will emit compile errors. |
| ... | ... | @@ -1600,16 +1604,17 @@ fn resolveConstValue( |
| 1600 | 1604 | block: *Block, |
| 1601 | 1605 | src: LazySrcLoc, |
| 1602 | 1606 | air_ref: Air.Inst.Ref, |
| 1607 | reason: []const u8, |
| 1603 | 1608 | ) CompileError!Value { |
| 1604 | 1609 | if (try sema.resolveMaybeUndefValAllowVariables(block, src, air_ref)) |val| { |
| 1605 | 1610 | switch (val.tag()) { |
| 1606 | 1611 | .undef => return sema.failWithUseOfUndef(block, src), |
| 1607 | | .variable => return sema.failWithNeededComptime(block, src), |
| 1612 | .variable => return sema.failWithNeededComptime(block, src, reason), |
| 1608 | 1613 | .generic_poison => return error.GenericPoison, |
| 1609 | 1614 | else => return val, |
| 1610 | 1615 | } |
| 1611 | 1616 | } |
| 1612 | | return sema.failWithNeededComptime(block, src); |
| 1617 | return sema.failWithNeededComptime(block, src, reason); |
| 1613 | 1618 | } |
| 1614 | 1619 | |
| 1615 | 1620 | /// Value Tag `variable` causes this function to return `null`. |
| ... | ... | @@ -1697,8 +1702,15 @@ fn resolveMaybeUndefValAllowVariables( |
| 1697 | 1702 | } |
| 1698 | 1703 | } |
| 1699 | 1704 | |
| 1700 | | fn failWithNeededComptime(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError { |
| 1701 | | return sema.fail(block, src, "unable to resolve comptime value", .{}); |
| 1705 | fn failWithNeededComptime(sema: *Sema, block: *Block, src: LazySrcLoc, reason: []const u8) CompileError { |
| 1706 | const msg = msg: { |
| 1707 | const msg = try sema.errMsg(block, src, "unable to resolve comptime value", .{}); |
| 1708 | errdefer msg.destroy(sema.gpa); |
| 1709 | |
| 1710 | try sema.errNote(block, src, msg, "{s}", .{reason}); |
| 1711 | break :msg msg; |
| 1712 | }; |
| 1713 | return sema.failWithOwnedErrorMsg(block, msg); |
| 1702 | 1714 | } |
| 1703 | 1715 | |
| 1704 | 1716 | fn failWithUseOfUndef(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError { |
| ... | ... | @@ -1870,15 +1882,24 @@ fn analyzeAsAlign( |
| 1870 | 1882 | src: LazySrcLoc, |
| 1871 | 1883 | air_ref: Air.Inst.Ref, |
| 1872 | 1884 | ) !u32 { |
| 1873 | | const alignment_big = try sema.analyzeAsInt(block, src, air_ref, align_ty); |
| 1885 | const alignment_big = try sema.analyzeAsInt(block, src, air_ref, align_ty, "alignment must be comptime known"); |
| 1874 | 1886 | const alignment = @intCast(u32, alignment_big); // We coerce to u16 in the prev line. |
| 1887 | try sema.validateAlign(block, src, alignment); |
| 1888 | return alignment; |
| 1889 | } |
| 1890 | |
| 1891 | fn validateAlign( |
| 1892 | sema: *Sema, |
| 1893 | block: *Block, |
| 1894 | src: LazySrcLoc, |
| 1895 | alignment: u32, |
| 1896 | ) !void { |
| 1875 | 1897 | if (alignment == 0) return sema.fail(block, src, "alignment must be >= 1", .{}); |
| 1876 | 1898 | if (!std.math.isPowerOfTwo(alignment)) { |
| 1877 | 1899 | return sema.fail(block, src, "alignment value '{d}' is not a power of two", .{ |
| 1878 | 1900 | alignment, |
| 1879 | 1901 | }); |
| 1880 | 1902 | } |
| 1881 | | return alignment; |
| 1882 | 1903 | } |
| 1883 | 1904 | |
| 1884 | 1905 | pub fn resolveAlign( |
| ... | ... | @@ -1897,9 +1918,10 @@ fn resolveInt( |
| 1897 | 1918 | src: LazySrcLoc, |
| 1898 | 1919 | zir_ref: Zir.Inst.Ref, |
| 1899 | 1920 | dest_ty: Type, |
| 1921 | reason: []const u8, |
| 1900 | 1922 | ) !u64 { |
| 1901 | 1923 | const air_ref = try sema.resolveInst(zir_ref); |
| 1902 | | return analyzeAsInt(sema, block, src, air_ref, dest_ty); |
| 1924 | return analyzeAsInt(sema, block, src, air_ref, dest_ty, reason); |
| 1903 | 1925 | } |
| 1904 | 1926 | |
| 1905 | 1927 | fn analyzeAsInt( |
| ... | ... | @@ -1908,9 +1930,10 @@ fn analyzeAsInt( |
| 1908 | 1930 | src: LazySrcLoc, |
| 1909 | 1931 | air_ref: Air.Inst.Ref, |
| 1910 | 1932 | dest_ty: Type, |
| 1933 | reason: []const u8, |
| 1911 | 1934 | ) !u64 { |
| 1912 | 1935 | const coerced = try sema.coerce(block, dest_ty, air_ref, src); |
| 1913 | | const val = try sema.resolveConstValue(block, src, coerced); |
| 1936 | const val = try sema.resolveConstValue(block, src, coerced, reason); |
| 1914 | 1937 | const target = sema.mod.getTarget(); |
| 1915 | 1938 | return (try val.getUnsignedIntAdvanced(target, sema.kit(block, src))).?; |
| 1916 | 1939 | } |
| ... | ... | @@ -1922,9 +1945,10 @@ pub fn resolveInstConst( |
| 1922 | 1945 | block: *Block, |
| 1923 | 1946 | src: LazySrcLoc, |
| 1924 | 1947 | zir_ref: Zir.Inst.Ref, |
| 1948 | reason: []const u8, |
| 1925 | 1949 | ) CompileError!TypedValue { |
| 1926 | 1950 | const air_ref = try sema.resolveInst(zir_ref); |
| 1927 | | const val = try sema.resolveConstValue(block, src, air_ref); |
| 1951 | const val = try sema.resolveConstValue(block, src, air_ref, reason); |
| 1928 | 1952 | return TypedValue{ |
| 1929 | 1953 | .ty = sema.typeOf(air_ref), |
| 1930 | 1954 | .val = val, |
| ... | ... | @@ -1938,9 +1962,10 @@ pub fn resolveInstValue( |
| 1938 | 1962 | block: *Block, |
| 1939 | 1963 | src: LazySrcLoc, |
| 1940 | 1964 | zir_ref: Zir.Inst.Ref, |
| 1965 | reason: []const u8, |
| 1941 | 1966 | ) CompileError!TypedValue { |
| 1942 | 1967 | const air_ref = try sema.resolveInst(zir_ref); |
| 1943 | | const val = try sema.resolveValue(block, src, air_ref); |
| 1968 | const val = try sema.resolveValue(block, src, air_ref, reason); |
| 1944 | 1969 | return TypedValue{ |
| 1945 | 1970 | .ty = sema.typeOf(air_ref), |
| 1946 | 1971 | .val = val, |
| ... | ... | @@ -1974,7 +1999,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 1974 | 1999 | defer trash_block.instructions.deinit(sema.gpa); |
| 1975 | 2000 | const operand = try trash_block.addBitCast(pointee_ty, .void_value); |
| 1976 | 2001 | |
| 1977 | | try sema.requireRuntimeBlock(block, src); |
| 2002 | try sema.requireFunctionBlock(block, src); |
| 1978 | 2003 | const ptr_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 1979 | 2004 | .pointee_type = pointee_ty, |
| 1980 | 2005 | .@"align" = inferred_alloc.alignment, |
| ... | ... | @@ -2259,7 +2284,7 @@ fn createAnonymousDeclTypeNamed( |
| 2259 | 2284 | const arg = sema.inst_map.get(zir_inst).?; |
| 2260 | 2285 | // The comptime call code in analyzeCall already did this, so we're |
| 2261 | 2286 | // just repeating it here and it's guaranteed to work. |
| 2262 | | const arg_val = sema.resolveConstMaybeUndefVal(block, .unneeded, arg) catch unreachable; |
| 2287 | const arg_val = sema.resolveConstMaybeUndefVal(block, .unneeded, arg, undefined) catch unreachable; |
| 2263 | 2288 | |
| 2264 | 2289 | if (arg_i != 0) try buf.appendSlice(","); |
| 2265 | 2290 | try buf.writer().print("{}", .{arg_val.fmtValue(sema.typeOf(arg), sema.mod)}); |
| ... | ... | @@ -2319,6 +2344,7 @@ fn zirEnumDecl( |
| 2319 | 2344 | extra_index += 1; |
| 2320 | 2345 | break :blk LazySrcLoc.nodeOffset(node_offset); |
| 2321 | 2346 | } else sema.src; |
| 2347 | const tag_ty_src: LazySrcLoc = .{ .node_offset_container_tag = src.node_offset.x }; |
| 2322 | 2348 | |
| 2323 | 2349 | const tag_type_ref = if (small.has_tag_type) blk: { |
| 2324 | 2350 | const tag_type_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); |
| ... | ... | @@ -2344,8 +2370,10 @@ fn zirEnumDecl( |
| 2344 | 2370 | break :blk decls_len; |
| 2345 | 2371 | } else 0; |
| 2346 | 2372 | |
| 2373 | var done = false; |
| 2374 | |
| 2347 | 2375 | var new_decl_arena = std.heap.ArenaAllocator.init(gpa); |
| 2348 | | errdefer new_decl_arena.deinit(); |
| 2376 | errdefer if (!done) new_decl_arena.deinit(); |
| 2349 | 2377 | const new_decl_arena_allocator = new_decl_arena.allocator(); |
| 2350 | 2378 | |
| 2351 | 2379 | const enum_obj = try new_decl_arena_allocator.create(Module.EnumFull); |
| ... | ... | @@ -2362,7 +2390,7 @@ fn zirEnumDecl( |
| 2362 | 2390 | }, small.name_strategy, "enum", inst); |
| 2363 | 2391 | const new_decl = mod.declPtr(new_decl_index); |
| 2364 | 2392 | new_decl.owns_tv = true; |
| 2365 | | errdefer mod.abortAnonDecl(new_decl_index); |
| 2393 | errdefer if (!done) mod.abortAnonDecl(new_decl_index); |
| 2366 | 2394 | |
| 2367 | 2395 | enum_obj.* = .{ |
| 2368 | 2396 | .owner_decl = new_decl_index, |
| ... | ... | @@ -2381,19 +2409,28 @@ fn zirEnumDecl( |
| 2381 | 2409 | &enum_obj.namespace, new_decl, new_decl.name, |
| 2382 | 2410 | }); |
| 2383 | 2411 | |
| 2412 | try new_decl.finalizeNewArena(&new_decl_arena); |
| 2413 | const decl_val = try sema.analyzeDeclVal(block, src, new_decl_index); |
| 2414 | done = true; |
| 2415 | |
| 2416 | var decl_arena = new_decl.value_arena.?.promote(gpa); |
| 2417 | defer new_decl.value_arena.?.* = decl_arena.state; |
| 2418 | const decl_arena_allocator = decl_arena.allocator(); |
| 2419 | |
| 2384 | 2420 | extra_index = try mod.scanNamespace(&enum_obj.namespace, extra_index, decls_len, new_decl); |
| 2385 | 2421 | |
| 2386 | 2422 | const body = sema.code.extra[extra_index..][0..body_len]; |
| 2387 | 2423 | if (fields_len == 0) { |
| 2388 | 2424 | assert(body.len == 0); |
| 2389 | 2425 | if (tag_type_ref != .none) { |
| 2390 | | // TODO better source location |
| 2391 | | const ty = try sema.resolveType(block, src, tag_type_ref); |
| 2426 | const ty = try sema.resolveType(block, tag_ty_src, tag_type_ref); |
| 2427 | if (ty.zigTypeTag() != .Int and ty.zigTypeTag() != .ComptimeInt) { |
| 2428 | return sema.fail(block, tag_ty_src, "expected integer tag type, found '{}'", .{ty.fmt(sema.mod)}); |
| 2429 | } |
| 2392 | 2430 | enum_obj.tag_ty = try ty.copy(new_decl_arena_allocator); |
| 2393 | 2431 | enum_obj.tag_ty_inferred = false; |
| 2394 | 2432 | } |
| 2395 | | try new_decl.finalizeNewArena(&new_decl_arena); |
| 2396 | | return sema.analyzeDeclVal(block, src, new_decl_index); |
| 2433 | return decl_val; |
| 2397 | 2434 | } |
| 2398 | 2435 | extra_index += body.len; |
| 2399 | 2436 | |
| ... | ... | @@ -2446,13 +2483,15 @@ fn zirEnumDecl( |
| 2446 | 2483 | try wip_captures.finalize(); |
| 2447 | 2484 | |
| 2448 | 2485 | if (tag_type_ref != .none) { |
| 2449 | | // TODO better source location |
| 2450 | | const ty = try sema.resolveType(block, src, tag_type_ref); |
| 2451 | | enum_obj.tag_ty = try ty.copy(new_decl_arena_allocator); |
| 2486 | const ty = try sema.resolveType(block, tag_ty_src, tag_type_ref); |
| 2487 | if (ty.zigTypeTag() != .Int and ty.zigTypeTag() != .ComptimeInt) { |
| 2488 | return sema.fail(block, tag_ty_src, "expected integer tag type, found '{}'", .{ty.fmt(sema.mod)}); |
| 2489 | } |
| 2490 | enum_obj.tag_ty = try ty.copy(decl_arena_allocator); |
| 2452 | 2491 | enum_obj.tag_ty_inferred = false; |
| 2453 | 2492 | } else { |
| 2454 | 2493 | const bits = std.math.log2_int_ceil(usize, fields_len); |
| 2455 | | enum_obj.tag_ty = try Type.Tag.int_unsigned.create(new_decl_arena_allocator, bits); |
| 2494 | enum_obj.tag_ty = try Type.Tag.int_unsigned.create(decl_arena_allocator, bits); |
| 2456 | 2495 | enum_obj.tag_ty_inferred = true; |
| 2457 | 2496 | } |
| 2458 | 2497 | } |
| ... | ... | @@ -2463,12 +2502,12 @@ fn zirEnumDecl( |
| 2463 | 2502 | } |
| 2464 | 2503 | } |
| 2465 | 2504 | |
| 2466 | | try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len); |
| 2505 | try enum_obj.fields.ensureTotalCapacity(decl_arena_allocator, fields_len); |
| 2467 | 2506 | const any_values = for (sema.code.extra[body_end..][0..bit_bags_count]) |bag| { |
| 2468 | 2507 | if (bag != 0) break true; |
| 2469 | 2508 | } else false; |
| 2470 | 2509 | if (any_values) { |
| 2471 | | try enum_obj.values.ensureTotalCapacityContext(new_decl_arena_allocator, fields_len, .{ |
| 2510 | try enum_obj.values.ensureTotalCapacityContext(decl_arena_allocator, fields_len, .{ |
| 2472 | 2511 | .ty = enum_obj.tag_ty, |
| 2473 | 2512 | .mod = mod, |
| 2474 | 2513 | }); |
| ... | ... | @@ -2493,7 +2532,7 @@ fn zirEnumDecl( |
| 2493 | 2532 | extra_index += 1; |
| 2494 | 2533 | |
| 2495 | 2534 | // This string needs to outlive the ZIR code. |
| 2496 | | const field_name = try new_decl_arena_allocator.dupe(u8, field_name_zir); |
| 2535 | const field_name = try decl_arena_allocator.dupe(u8, field_name_zir); |
| 2497 | 2536 | |
| 2498 | 2537 | const gop = enum_obj.fields.getOrPutAssumeCapacity(field_name); |
| 2499 | 2538 | if (gop.found_existing) { |
| ... | ... | @@ -2515,9 +2554,9 @@ fn zirEnumDecl( |
| 2515 | 2554 | // TODO: if we need to report an error here, use a source location |
| 2516 | 2555 | // that points to this default value expression rather than the struct. |
| 2517 | 2556 | // But only resolve the source location if we need to emit a compile error. |
| 2518 | | const tag_val = (try sema.resolveInstConst(block, src, tag_val_ref)).val; |
| 2557 | const tag_val = (try sema.resolveInstConst(block, src, tag_val_ref, "enum tag value must be comptime known")).val; |
| 2519 | 2558 | last_tag_val = tag_val; |
| 2520 | | const copied_tag_val = try tag_val.copy(new_decl_arena_allocator); |
| 2559 | const copied_tag_val = try tag_val.copy(decl_arena_allocator); |
| 2521 | 2560 | enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{ |
| 2522 | 2561 | .ty = enum_obj.tag_ty, |
| 2523 | 2562 | .mod = mod, |
| ... | ... | @@ -2528,16 +2567,14 @@ fn zirEnumDecl( |
| 2528 | 2567 | else |
| 2529 | 2568 | Value.zero; |
| 2530 | 2569 | last_tag_val = tag_val; |
| 2531 | | const copied_tag_val = try tag_val.copy(new_decl_arena_allocator); |
| 2570 | const copied_tag_val = try tag_val.copy(decl_arena_allocator); |
| 2532 | 2571 | enum_obj.values.putAssumeCapacityNoClobberContext(copied_tag_val, {}, .{ |
| 2533 | 2572 | .ty = enum_obj.tag_ty, |
| 2534 | 2573 | .mod = mod, |
| 2535 | 2574 | }); |
| 2536 | 2575 | } |
| 2537 | 2576 | } |
| 2538 | | |
| 2539 | | try new_decl.finalizeNewArena(&new_decl_arena); |
| 2540 | | return sema.analyzeDeclVal(block, src, new_decl_index); |
| 2577 | return decl_val; |
| 2541 | 2578 | } |
| 2542 | 2579 | |
| 2543 | 2580 | fn zirUnionDecl( |
| ... | ... | @@ -2738,7 +2775,6 @@ fn zirRetPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 2738 | 2775 | |
| 2739 | 2776 | const inst_data = sema.code.instructions.items(.data)[inst].node; |
| 2740 | 2777 | const src = LazySrcLoc.nodeOffset(inst_data); |
| 2741 | | try sema.requireFunctionBlock(block, src); |
| 2742 | 2778 | |
| 2743 | 2779 | if (block.is_comptime or try sema.typeRequiresComptime(block, src, sema.fn_ret_ty)) { |
| 2744 | 2780 | const fn_ret_ty = try sema.resolveTypeFields(block, src, sema.fn_ret_ty); |
| ... | ... | @@ -2770,16 +2806,6 @@ fn zirRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 2770 | 2806 | return sema.analyzeRef(block, inst_data.src(), operand); |
| 2771 | 2807 | } |
| 2772 | 2808 | |
| 2773 | | fn zirRetType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 2774 | | const tracy = trace(@src()); |
| 2775 | | defer tracy.end(); |
| 2776 | | |
| 2777 | | const inst_data = sema.code.instructions.items(.data)[inst].node; |
| 2778 | | const src = LazySrcLoc.nodeOffset(inst_data); |
| 2779 | | try sema.requireFunctionBlock(block, src); |
| 2780 | | return sema.addType(sema.fn_ret_ty); |
| 2781 | | } |
| 2782 | | |
| 2783 | 2809 | fn zirEnsureResultUsed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 2784 | 2810 | const tracy = trace(@src()); |
| 2785 | 2811 | defer tracy.end(); |
| ... | ... | @@ -2925,7 +2951,7 @@ fn zirAllocExtended( |
| 2925 | 2951 | try sema.validateVarType(block, ty_src, var_ty, false); |
| 2926 | 2952 | } |
| 2927 | 2953 | const target = sema.mod.getTarget(); |
| 2928 | | try sema.requireRuntimeBlock(block, src); |
| 2954 | try sema.requireFunctionBlock(block, src); |
| 2929 | 2955 | try sema.resolveTypeLayout(block, src, var_ty); |
| 2930 | 2956 | const ptr_type = try Type.ptr(sema.arena, sema.mod, .{ |
| 2931 | 2957 | .pointee_type = var_ty, |
| ... | ... | @@ -3024,7 +3050,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 3024 | 3050 | return sema.addConstant(const_ptr_ty, val); |
| 3025 | 3051 | } |
| 3026 | 3052 | |
| 3027 | | try sema.requireRuntimeBlock(block, src); |
| 3053 | try sema.requireFunctionBlock(block, src); |
| 3028 | 3054 | return block.addBitCast(const_ptr_ty, alloc); |
| 3029 | 3055 | } |
| 3030 | 3056 | |
| ... | ... | @@ -3061,7 +3087,7 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I |
| 3061 | 3087 | .pointee_type = var_ty, |
| 3062 | 3088 | .@"addrspace" = target_util.defaultAddressSpace(target, .local), |
| 3063 | 3089 | }); |
| 3064 | | try sema.requireRuntimeBlock(block, var_decl_src); |
| 3090 | try sema.requireFunctionBlock(block, var_decl_src); |
| 3065 | 3091 | try sema.queueFullTypeResolution(var_ty); |
| 3066 | 3092 | return block.addTy(.alloc, ptr_type); |
| 3067 | 3093 | } |
| ... | ... | @@ -3083,7 +3109,7 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 3083 | 3109 | .pointee_type = var_ty, |
| 3084 | 3110 | .@"addrspace" = target_util.defaultAddressSpace(target, .local), |
| 3085 | 3111 | }); |
| 3086 | | try sema.requireRuntimeBlock(block, var_decl_src); |
| 3112 | try sema.requireFunctionBlock(block, var_decl_src); |
| 3087 | 3113 | try sema.queueFullTypeResolution(var_ty); |
| 3088 | 3114 | return block.addTy(.alloc, ptr_type); |
| 3089 | 3115 | } |
| ... | ... | @@ -3272,7 +3298,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 3272 | 3298 | return; |
| 3273 | 3299 | } |
| 3274 | 3300 | |
| 3275 | | try sema.requireRuntimeBlock(block, src); |
| 3301 | try sema.requireFunctionBlock(block, src); |
| 3276 | 3302 | try sema.queueFullTypeResolution(final_elem_ty); |
| 3277 | 3303 | |
| 3278 | 3304 | // Change it to a normal alloc. |
| ... | ... | @@ -3593,7 +3619,7 @@ fn validateUnionInit( |
| 3593 | 3619 | return; |
| 3594 | 3620 | } |
| 3595 | 3621 | |
| 3596 | | try sema.requireRuntimeBlock(block, init_src); |
| 3622 | try sema.requireFunctionBlock(block, init_src); |
| 3597 | 3623 | const new_tag = try sema.addConstant(union_obj.tag_ty, tag_val); |
| 3598 | 3624 | _ = try block.addBinOp(.set_union_tag, union_ptr, new_tag); |
| 3599 | 3625 | } |
| ... | ... | @@ -3859,7 +3885,7 @@ fn zirValidateArrayInit( |
| 3859 | 3885 | // any ZIR instructions at comptime; we need to do that here. |
| 3860 | 3886 | if (array_ty.sentinel()) |sentinel_val| { |
| 3861 | 3887 | const array_len_ref = try sema.addIntUnsigned(Type.usize, array_len); |
| 3862 | | const sentinel_ptr = try sema.elemPtrArray(block, init_src, array_ptr, init_src, array_len_ref, true); |
| 3888 | const sentinel_ptr = try sema.elemPtrArray(block, init_src, init_src, array_ptr, init_src, array_len_ref, true); |
| 3863 | 3889 | const sentinel = try sema.addConstant(array_ty.childType(), sentinel_val); |
| 3864 | 3890 | try sema.storePtr2(block, init_src, sentinel_ptr, init_src, sentinel, init_src, .store); |
| 3865 | 3891 | } |
| ... | ... | @@ -4207,10 +4233,8 @@ fn storeToInferredAllocComptime( |
| 4207 | 4233 | const operand_ty = sema.typeOf(operand); |
| 4208 | 4234 | // There will be only one store_to_inferred_ptr because we are running at comptime. |
| 4209 | 4235 | // The alloc will turn into a Decl. |
| 4210 | | if (try sema.resolveMaybeUndefValAllowVariables(block, src, operand)) |operand_val| { |
| 4211 | | if (operand_val.tag() == .variable) { |
| 4212 | | return sema.failWithNeededComptime(block, src); |
| 4213 | | } |
| 4236 | if (try sema.resolveMaybeUndefValAllowVariables(block, src, operand)) |operand_val| store: { |
| 4237 | if (operand_val.tag() == .variable) break :store; |
| 4214 | 4238 | var anon_decl = try block.startAnonDecl(src); |
| 4215 | 4239 | defer anon_decl.deinit(); |
| 4216 | 4240 | iac.data.decl_index = try anon_decl.finish( |
| ... | ... | @@ -4219,15 +4243,15 @@ fn storeToInferredAllocComptime( |
| 4219 | 4243 | iac.data.alignment, |
| 4220 | 4244 | ); |
| 4221 | 4245 | return; |
| 4222 | | } else { |
| 4223 | | return sema.failWithNeededComptime(block, src); |
| 4224 | 4246 | } |
| 4247 | |
| 4248 | return sema.failWithNeededComptime(block, src, "value being stored to a comptime variable must be comptime known"); |
| 4225 | 4249 | } |
| 4226 | 4250 | |
| 4227 | 4251 | fn zirSetEvalBranchQuota(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 4228 | 4252 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 4229 | 4253 | const src = inst_data.src(); |
| 4230 | | const quota = @intCast(u32, try sema.resolveInt(block, src, inst_data.operand, Type.u32)); |
| 4254 | const quota = @intCast(u32, try sema.resolveInt(block, src, inst_data.operand, Type.u32, "eval branch quota must be comptime known")); |
| 4231 | 4255 | sema.branch_quota = @maximum(sema.branch_quota, quota); |
| 4232 | 4256 | } |
| 4233 | 4257 | |
| ... | ... | @@ -4282,7 +4306,7 @@ fn zirParamType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 4282 | 4306 | var param_index = inst_data.param_index; |
| 4283 | 4307 | |
| 4284 | 4308 | const fn_ty = if (callee_ty.tag() == .bound_fn) fn_ty: { |
| 4285 | | const bound_fn_val = try sema.resolveConstValue(block, callee_src, callee); |
| 4309 | const bound_fn_val = try sema.resolveConstValue(block, .unneeded, callee, undefined); |
| 4286 | 4310 | const bound_fn = bound_fn_val.castTag(.bound_fn).?.data; |
| 4287 | 4311 | const fn_ty = sema.typeOf(bound_fn.func_inst); |
| 4288 | 4312 | param_index += 1; |
| ... | ... | @@ -4417,7 +4441,7 @@ fn zirCompileError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 4417 | 4441 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 4418 | 4442 | const src = inst_data.src(); |
| 4419 | 4443 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 4420 | | const msg = try sema.resolveConstString(block, operand_src, inst_data.operand); |
| 4444 | const msg = try sema.resolveConstString(block, operand_src, inst_data.operand, "compile error string must be comptime known"); |
| 4421 | 4445 | return sema.fail(block, src, "{s}", .{msg}); |
| 4422 | 4446 | } |
| 4423 | 4447 | |
| ... | ... | @@ -4466,7 +4490,7 @@ fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index, force_comptime: bo |
| 4466 | 4490 | if (block.is_comptime or force_comptime) { |
| 4467 | 4491 | return sema.fail(block, src, "encountered @panic at comptime", .{}); |
| 4468 | 4492 | } |
| 4469 | | try sema.requireRuntimeBlock(block, src); |
| 4493 | try sema.requireFunctionBlock(block, src); |
| 4470 | 4494 | return sema.panicWithMsg(block, src, msg_inst); |
| 4471 | 4495 | } |
| 4472 | 4496 | |
| ... | ... | @@ -4854,7 +4878,7 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 4854 | 4878 | const src = inst_data.src(); |
| 4855 | 4879 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 4856 | 4880 | const options_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; |
| 4857 | | const operand = try sema.resolveInstConst(block, operand_src, extra.operand); |
| 4881 | const operand = try sema.resolveInstConst(block, operand_src, extra.operand, "export target must be comptime known"); |
| 4858 | 4882 | const options = try sema.resolveExportOptions(block, options_src, extra.options); |
| 4859 | 4883 | const decl_index = switch (operand.val.tag()) { |
| 4860 | 4884 | .function => operand.val.castTag(.function).?.data.owner_decl, |
| ... | ... | @@ -4989,7 +5013,7 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst |
| 4989 | 5013 | fn zirSetCold(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 4990 | 5014 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 4991 | 5015 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 4992 | | const is_cold = try sema.resolveConstBool(block, operand_src, inst_data.operand); |
| 5016 | const is_cold = try sema.resolveConstBool(block, operand_src, inst_data.operand, "operand to @setCold must be comptime known"); |
| 4993 | 5017 | const func = sema.func orelse return; // does nothing outside a function |
| 4994 | 5018 | func.is_cold = is_cold; |
| 4995 | 5019 | } |
| ... | ... | @@ -4997,7 +5021,7 @@ fn zirSetCold(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi |
| 4997 | 5021 | fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void { |
| 4998 | 5022 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; |
| 4999 | 5023 | const src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node }; |
| 5000 | | const float_mode = try sema.resolveBuiltinEnum(block, src, extra.operand, "FloatMode"); |
| 5024 | const float_mode = try sema.resolveBuiltinEnum(block, src, extra.operand, "FloatMode", "operand to @setFloatMode must be comptime known"); |
| 5001 | 5025 | switch (float_mode) { |
| 5002 | 5026 | .Strict => return, |
| 5003 | 5027 | .Optimized => { |
| ... | ... | @@ -5009,7 +5033,7 @@ fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD |
| 5009 | 5033 | fn zirSetRuntimeSafety(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 5010 | 5034 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 5011 | 5035 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 5012 | | block.want_safety = try sema.resolveConstBool(block, operand_src, inst_data.operand); |
| 5036 | block.want_safety = try sema.resolveConstBool(block, operand_src, inst_data.operand, "operand to @setRuntimeSafety must be comptime known"); |
| 5013 | 5037 | } |
| 5014 | 5038 | |
| 5015 | 5039 | fn zirFence(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void { |
| ... | ... | @@ -5017,7 +5041,7 @@ fn zirFence(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) Co |
| 5017 | 5041 | |
| 5018 | 5042 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; |
| 5019 | 5043 | const order_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node }; |
| 5020 | | const order = try sema.resolveAtomicOrder(block, order_src, extra.operand); |
| 5044 | const order = try sema.resolveAtomicOrder(block, order_src, extra.operand, "atomic order of @fence must be comptime known"); |
| 5021 | 5045 | |
| 5022 | 5046 | if (@enumToInt(order) < @enumToInt(std.builtin.AtomicOrder.Acquire)) { |
| 5023 | 5047 | return sema.fail(block, order_src, "atomic ordering must be Acquire or stricter", .{}); |
| ... | ... | @@ -5292,7 +5316,7 @@ fn zirCall( |
| 5292 | 5316 | |
| 5293 | 5317 | // Desugar bound functions here |
| 5294 | 5318 | if (func_type.tag() == .bound_fn) { |
| 5295 | | const bound_func = try sema.resolveValue(block, func_src, func); |
| 5319 | const bound_func = try sema.resolveValue(block, .unneeded, func, undefined); |
| 5296 | 5320 | const bound_data = &bound_func.cast(Value.Payload.BoundFn).?.data; |
| 5297 | 5321 | func = bound_data.func_inst; |
| 5298 | 5322 | resolved_args = try sema.arena.alloc(Air.Inst.Ref, args.len + 1); |
| ... | ... | @@ -5489,7 +5513,8 @@ fn analyzeCall( |
| 5489 | 5513 | } |
| 5490 | 5514 | |
| 5491 | 5515 | const result: Air.Inst.Ref = if (is_inline_call) res: { |
| 5492 | | const func_val = try sema.resolveConstValue(block, func_src, func); |
| 5516 | // TODO explain why function is being called at comptime |
| 5517 | const func_val = try sema.resolveConstValue(block, func_src, func, "function being called at comptime must be comptime known"); |
| 5493 | 5518 | const module_fn = switch (func_val.tag()) { |
| 5494 | 5519 | .decl_ref => mod.declPtr(func_val.castTag(.decl_ref).?.data).val.castTag(.function).?.data, |
| 5495 | 5520 | .function => func_val.castTag(.function).?.data, |
| ... | ... | @@ -5588,82 +5613,39 @@ fn analyzeCall( |
| 5588 | 5613 | // which means its parameter type expressions must be resolved in order and used |
| 5589 | 5614 | // to successively coerce the arguments. |
| 5590 | 5615 | const fn_info = sema.code.getFnInfo(module_fn.zir_body_inst); |
| 5591 | | const zir_tags = sema.code.instructions.items(.tag); |
| 5592 | 5616 | var arg_i: usize = 0; |
| 5593 | | for (fn_info.param_body) |inst| switch (zir_tags[inst]) { |
| 5594 | | .param, .param_comptime => { |
| 5595 | | // Evaluate the parameter type expression now that previous ones have |
| 5596 | | // been mapped, and coerce the corresponding argument to it. |
| 5597 | | const pl_tok = sema.code.instructions.items(.data)[inst].pl_tok; |
| 5598 | | const param_src = pl_tok.src(); |
| 5599 | | const extra = sema.code.extraData(Zir.Inst.Param, pl_tok.payload_index); |
| 5600 | | const param_body = sema.code.extra[extra.end..][0..extra.data.body_len]; |
| 5601 | | const param_ty_inst = try sema.resolveBody(&child_block, param_body, inst); |
| 5602 | | const param_ty = try sema.analyzeAsType(&child_block, param_src, param_ty_inst); |
| 5603 | | new_fn_info.param_types[arg_i] = param_ty; |
| 5604 | | const arg_src = call_src; // TODO: better source location |
| 5605 | | const casted_arg = try sema.coerce(&child_block, param_ty, uncasted_args[arg_i], arg_src); |
| 5606 | | try sema.inst_map.putNoClobber(gpa, inst, casted_arg); |
| 5607 | | |
| 5608 | | if (is_comptime_call) { |
| 5609 | | const arg_val = try sema.resolveConstMaybeUndefVal(&child_block, arg_src, casted_arg); |
| 5610 | | switch (arg_val.tag()) { |
| 5611 | | .generic_poison, .generic_poison_type => { |
| 5612 | | // This function is currently evaluated as part of an as-of-yet unresolvable |
| 5613 | | // parameter or return type. |
| 5614 | | return error.GenericPoison; |
| 5615 | | }, |
| 5616 | | else => { |
| 5617 | | // Needed so that lazy values do not trigger |
| 5618 | | // assertion due to type not being resolved |
| 5619 | | // when the hash function is called. |
| 5620 | | try sema.resolveLazyValue(&child_block, arg_src, arg_val); |
| 5621 | | }, |
| 5622 | | } |
| 5623 | | should_memoize = should_memoize and !arg_val.canMutateComptimeVarState(); |
| 5624 | | memoized_call_key.args[arg_i] = .{ |
| 5625 | | .ty = param_ty, |
| 5626 | | .val = arg_val, |
| 5627 | | }; |
| 5628 | | } |
| 5629 | | |
| 5630 | | arg_i += 1; |
| 5631 | | continue; |
| 5632 | | }, |
| 5633 | | .param_anytype, .param_anytype_comptime => { |
| 5634 | | // No coercion needed. |
| 5635 | | const uncasted_arg = uncasted_args[arg_i]; |
| 5636 | | new_fn_info.param_types[arg_i] = sema.typeOf(uncasted_arg); |
| 5637 | | try sema.inst_map.putNoClobber(gpa, inst, uncasted_arg); |
| 5638 | | |
| 5639 | | if (is_comptime_call) { |
| 5640 | | const arg_src = call_src; // TODO: better source location |
| 5641 | | const arg_val = try sema.resolveConstMaybeUndefVal(&child_block, arg_src, uncasted_arg); |
| 5642 | | switch (arg_val.tag()) { |
| 5643 | | .generic_poison, .generic_poison_type => { |
| 5644 | | // This function is currently evaluated as part of an as-of-yet unresolvable |
| 5645 | | // parameter or return type. |
| 5646 | | return error.GenericPoison; |
| 5647 | | }, |
| 5648 | | else => { |
| 5649 | | // Needed so that lazy values do not trigger |
| 5650 | | // assertion due to type not being resolved |
| 5651 | | // when the hash function is called. |
| 5652 | | try sema.resolveLazyValue(&child_block, arg_src, arg_val); |
| 5653 | | }, |
| 5654 | | } |
| 5655 | | should_memoize = should_memoize and !arg_val.canMutateComptimeVarState(); |
| 5656 | | memoized_call_key.args[arg_i] = .{ |
| 5657 | | .ty = sema.typeOf(uncasted_arg), |
| 5658 | | .val = arg_val, |
| 5659 | | }; |
| 5660 | | } |
| 5661 | | |
| 5662 | | arg_i += 1; |
| 5663 | | continue; |
| 5664 | | }, |
| 5665 | | else => continue, |
| 5666 | | }; |
| 5617 | for (fn_info.param_body) |inst| { |
| 5618 | sema.analyzeInlineCallArg( |
| 5619 | &child_block, |
| 5620 | .unneeded, |
| 5621 | inst, |
| 5622 | new_fn_info, |
| 5623 | &arg_i, |
| 5624 | uncasted_args, |
| 5625 | is_comptime_call, |
| 5626 | &should_memoize, |
| 5627 | memoized_call_key, |
| 5628 | ) catch |err| switch (err) { |
| 5629 | error.NeededSourceLocation => { |
| 5630 | const decl = sema.mod.declPtr(block.src_decl); |
| 5631 | try sema.analyzeInlineCallArg( |
| 5632 | // Intentionally use the wrong block here since we know it's |
| 5633 | // going to fail and `argSrc` is relative to `block.src_decl`. |
| 5634 | block, |
| 5635 | Module.argSrc(call_src.node_offset.x, sema.gpa, decl, arg_i), |
| 5636 | inst, |
| 5637 | new_fn_info, |
| 5638 | &arg_i, |
| 5639 | uncasted_args, |
| 5640 | is_comptime_call, |
| 5641 | &should_memoize, |
| 5642 | memoized_call_key, |
| 5643 | ); |
| 5644 | return error.AnalysisFail; |
| 5645 | }, |
| 5646 | else => |e| return e, |
| 5647 | }; |
| 5648 | } |
| 5667 | 5649 | |
| 5668 | 5650 | // In case it is a generic function with an expression for the return type that depends |
| 5669 | 5651 | // on parameters, we must now do the same for the return type as we just did with |
| ... | ... | @@ -5719,6 +5701,7 @@ fn analyzeCall( |
| 5719 | 5701 | if (!is_comptime_call) { |
| 5720 | 5702 | try sema.emitDbgInline(block, parent_func.?, module_fn, new_func_resolved_ty, .dbg_inline_begin); |
| 5721 | 5703 | |
| 5704 | const zir_tags = sema.code.instructions.items(.tag); |
| 5722 | 5705 | for (fn_info.param_body) |param| switch (zir_tags[param]) { |
| 5723 | 5706 | .param, .param_comptime => { |
| 5724 | 5707 | const inst_data = sema.code.instructions.items(.data)[param].pl_tok; |
| ... | ... | @@ -5764,7 +5747,7 @@ fn analyzeCall( |
| 5764 | 5747 | } |
| 5765 | 5748 | |
| 5766 | 5749 | if (should_memoize and is_comptime_call) { |
| 5767 | | const result_val = try sema.resolveConstMaybeUndefVal(block, call_src, result); |
| 5750 | const result_val = try sema.resolveConstMaybeUndefVal(block, .unneeded, result, undefined); |
| 5768 | 5751 | |
| 5769 | 5752 | // TODO: check whether any external comptime memory was mutated by the |
| 5770 | 5753 | // comptime function call. If so, then do not memoize the call here. |
| ... | ... | @@ -5795,15 +5778,30 @@ fn analyzeCall( |
| 5795 | 5778 | break :res res2; |
| 5796 | 5779 | } else res: { |
| 5797 | 5780 | assert(!func_ty_info.is_generic); |
| 5798 | | try sema.requireRuntimeBlock(block, call_src); |
| 5781 | try sema.requireFunctionBlock(block, call_src); |
| 5799 | 5782 | |
| 5800 | 5783 | const args = try sema.arena.alloc(Air.Inst.Ref, uncasted_args.len); |
| 5801 | 5784 | for (uncasted_args) |uncasted_arg, i| { |
| 5802 | | const arg_src = call_src; // TODO: better source location |
| 5803 | 5785 | if (i < fn_params_len) { |
| 5804 | 5786 | const param_ty = func_ty.fnParamType(i); |
| 5805 | | try sema.resolveTypeFully(block, arg_src, param_ty); |
| 5806 | | args[i] = try sema.coerce(block, param_ty, uncasted_arg, arg_src); |
| 5787 | args[i] = sema.analyzeCallArg( |
| 5788 | block, |
| 5789 | .unneeded, |
| 5790 | param_ty, |
| 5791 | uncasted_arg, |
| 5792 | ) catch |err| switch (err) { |
| 5793 | error.NeededSourceLocation => { |
| 5794 | const decl = sema.mod.declPtr(block.src_decl); |
| 5795 | _ = try sema.analyzeCallArg( |
| 5796 | block, |
| 5797 | Module.argSrc(call_src.node_offset.x, sema.gpa, decl, i), |
| 5798 | param_ty, |
| 5799 | uncasted_arg, |
| 5800 | ); |
| 5801 | return error.AnalysisFail; |
| 5802 | }, |
| 5803 | else => |e| return e, |
| 5804 | }; |
| 5807 | 5805 | } else { |
| 5808 | 5806 | args[i] = uncasted_arg; |
| 5809 | 5807 | } |
| ... | ... | @@ -5835,6 +5833,136 @@ fn analyzeCall( |
| 5835 | 5833 | return result; |
| 5836 | 5834 | } |
| 5837 | 5835 | |
| 5836 | fn analyzeInlineCallArg( |
| 5837 | sema: *Sema, |
| 5838 | block: *Block, |
| 5839 | arg_src: LazySrcLoc, |
| 5840 | inst: Zir.Inst.Index, |
| 5841 | new_fn_info: Type.Payload.Function.Data, |
| 5842 | arg_i: *usize, |
| 5843 | uncasted_args: []const Air.Inst.Ref, |
| 5844 | is_comptime_call: bool, |
| 5845 | should_memoize: *bool, |
| 5846 | memoized_call_key: Module.MemoizedCall.Key, |
| 5847 | ) !void { |
| 5848 | const zir_tags = sema.code.instructions.items(.tag); |
| 5849 | switch (zir_tags[inst]) { |
| 5850 | .param, .param_comptime => { |
| 5851 | // Evaluate the parameter type expression now that previous ones have |
| 5852 | // been mapped, and coerce the corresponding argument to it. |
| 5853 | const pl_tok = sema.code.instructions.items(.data)[inst].pl_tok; |
| 5854 | const param_src = pl_tok.src(); |
| 5855 | const extra = sema.code.extraData(Zir.Inst.Param, pl_tok.payload_index); |
| 5856 | const param_body = sema.code.extra[extra.end..][0..extra.data.body_len]; |
| 5857 | const param_ty_inst = try sema.resolveBody(block, param_body, inst); |
| 5858 | const param_ty = try sema.analyzeAsType(block, param_src, param_ty_inst); |
| 5859 | new_fn_info.param_types[arg_i.*] = param_ty; |
| 5860 | const uncasted_arg = uncasted_args[arg_i.*]; |
| 5861 | if (try sema.typeRequiresComptime(block, arg_src, param_ty)) { |
| 5862 | _ = try sema.resolveConstMaybeUndefVal(block, arg_src, uncasted_arg, "argument to parameter with comptime only type must be comptime known"); |
| 5863 | } |
| 5864 | const casted_arg = try sema.coerce(block, param_ty, uncasted_arg, arg_src); |
| 5865 | try sema.inst_map.putNoClobber(sema.gpa, inst, casted_arg); |
| 5866 | |
| 5867 | if (is_comptime_call) { |
| 5868 | // TODO explain why function is being called at comptime |
| 5869 | const arg_val = try sema.resolveConstMaybeUndefVal(block, arg_src, casted_arg, "argument to function being called at comptime must be comptime known"); |
| 5870 | switch (arg_val.tag()) { |
| 5871 | .generic_poison, .generic_poison_type => { |
| 5872 | // This function is currently evaluated as part of an as-of-yet unresolvable |
| 5873 | // parameter or return type. |
| 5874 | return error.GenericPoison; |
| 5875 | }, |
| 5876 | else => { |
| 5877 | // Needed so that lazy values do not trigger |
| 5878 | // assertion due to type not being resolved |
| 5879 | // when the hash function is called. |
| 5880 | try sema.resolveLazyValue(block, arg_src, arg_val); |
| 5881 | }, |
| 5882 | } |
| 5883 | should_memoize.* = should_memoize.* and !arg_val.canMutateComptimeVarState(); |
| 5884 | memoized_call_key.args[arg_i.*] = .{ |
| 5885 | .ty = param_ty, |
| 5886 | .val = arg_val, |
| 5887 | }; |
| 5888 | } |
| 5889 | |
| 5890 | arg_i.* += 1; |
| 5891 | }, |
| 5892 | .param_anytype, .param_anytype_comptime => { |
| 5893 | // No coercion needed. |
| 5894 | const uncasted_arg = uncasted_args[arg_i.*]; |
| 5895 | new_fn_info.param_types[arg_i.*] = sema.typeOf(uncasted_arg); |
| 5896 | try sema.inst_map.putNoClobber(sema.gpa, inst, uncasted_arg); |
| 5897 | |
| 5898 | if (is_comptime_call) { |
| 5899 | // TODO explain why function is being called at comptime |
| 5900 | const arg_val = try sema.resolveConstMaybeUndefVal(block, arg_src, uncasted_arg, "argument to function being called at comptime must be comptime known"); |
| 5901 | switch (arg_val.tag()) { |
| 5902 | .generic_poison, .generic_poison_type => { |
| 5903 | // This function is currently evaluated as part of an as-of-yet unresolvable |
| 5904 | // parameter or return type. |
| 5905 | return error.GenericPoison; |
| 5906 | }, |
| 5907 | else => { |
| 5908 | // Needed so that lazy values do not trigger |
| 5909 | // assertion due to type not being resolved |
| 5910 | // when the hash function is called. |
| 5911 | try sema.resolveLazyValue(block, arg_src, arg_val); |
| 5912 | }, |
| 5913 | } |
| 5914 | should_memoize.* = should_memoize.* and !arg_val.canMutateComptimeVarState(); |
| 5915 | memoized_call_key.args[arg_i.*] = .{ |
| 5916 | .ty = sema.typeOf(uncasted_arg), |
| 5917 | .val = arg_val, |
| 5918 | }; |
| 5919 | } |
| 5920 | |
| 5921 | arg_i.* += 1; |
| 5922 | }, |
| 5923 | else => {}, |
| 5924 | } |
| 5925 | } |
| 5926 | |
| 5927 | fn analyzeCallArg( |
| 5928 | sema: *Sema, |
| 5929 | block: *Block, |
| 5930 | arg_src: LazySrcLoc, |
| 5931 | param_ty: Type, |
| 5932 | uncasted_arg: Air.Inst.Ref, |
| 5933 | ) !Air.Inst.Ref { |
| 5934 | try sema.resolveTypeFully(block, arg_src, param_ty); |
| 5935 | return sema.coerce(block, param_ty, uncasted_arg, arg_src); |
| 5936 | } |
| 5937 | |
| 5938 | fn analyzeGenericCallArg( |
| 5939 | sema: *Sema, |
| 5940 | block: *Block, |
| 5941 | arg_src: LazySrcLoc, |
| 5942 | uncasted_arg: Air.Inst.Ref, |
| 5943 | comptime_arg: TypedValue, |
| 5944 | runtime_args: []Air.Inst.Ref, |
| 5945 | new_fn_info: Type.Payload.Function.Data, |
| 5946 | runtime_i: *u32, |
| 5947 | ) !void { |
| 5948 | const is_runtime = comptime_arg.val.tag() == .generic_poison and |
| 5949 | comptime_arg.ty.hasRuntimeBits() and |
| 5950 | !(try sema.typeRequiresComptime(block, arg_src, comptime_arg.ty)); |
| 5951 | if (is_runtime) { |
| 5952 | const param_ty = new_fn_info.param_types[runtime_i.*]; |
| 5953 | const casted_arg = try sema.coerce(block, param_ty, uncasted_arg, arg_src); |
| 5954 | try sema.queueFullTypeResolution(param_ty); |
| 5955 | runtime_args[runtime_i.*] = casted_arg; |
| 5956 | runtime_i.* += 1; |
| 5957 | } |
| 5958 | } |
| 5959 | |
| 5960 | fn analyzeGenericCallArgVal(sema: *Sema, block: *Block, arg_src: LazySrcLoc, uncasted_arg: Air.Inst.Ref) !Value { |
| 5961 | const arg_val = try sema.resolveValue(block, arg_src, uncasted_arg, "parameter is comptime"); |
| 5962 | try sema.resolveLazyValue(block, arg_src, arg_val); |
| 5963 | return arg_val; |
| 5964 | } |
| 5965 | |
| 5838 | 5966 | fn instantiateGenericCall( |
| 5839 | 5967 | sema: *Sema, |
| 5840 | 5968 | block: *Block, |
| ... | ... | @@ -5849,7 +5977,7 @@ fn instantiateGenericCall( |
| 5849 | 5977 | const mod = sema.mod; |
| 5850 | 5978 | const gpa = sema.gpa; |
| 5851 | 5979 | |
| 5852 | | const func_val = try sema.resolveConstValue(block, func_src, func); |
| 5980 | const func_val = try sema.resolveConstValue(block, func_src, func, "generic function being called must be comptime known"); |
| 5853 | 5981 | const module_fn = switch (func_val.tag()) { |
| 5854 | 5982 | .function => func_val.castTag(.function).?.data, |
| 5855 | 5983 | .decl_ref => mod.declPtr(func_val.castTag(.decl_ref).?.data).val.castTag(.function).?.data, |
| ... | ... | @@ -5900,10 +6028,16 @@ fn instantiateGenericCall( |
| 5900 | 6028 | } |
| 5901 | 6029 | |
| 5902 | 6030 | if (is_comptime) { |
| 5903 | | const arg_src = call_src; // TODO better source location |
| 5904 | 6031 | const arg_ty = sema.typeOf(uncasted_args[i]); |
| 5905 | | const arg_val = try sema.resolveValue(block, arg_src, uncasted_args[i]); |
| 5906 | | try sema.resolveLazyValue(block, arg_src, arg_val); |
| 6032 | const arg_val = sema.analyzeGenericCallArgVal(block, .unneeded, uncasted_args[i]) catch |err| switch (err) { |
| 6033 | error.NeededSourceLocation => { |
| 6034 | const decl = sema.mod.declPtr(block.src_decl); |
| 6035 | const arg_src = Module.argSrc(call_src.node_offset.x, sema.gpa, decl, i); |
| 6036 | _ = try sema.analyzeGenericCallArgVal(block, arg_src, uncasted_args[i]); |
| 6037 | return error.AnalysisFail; |
| 6038 | }, |
| 6039 | else => |e| return e, |
| 6040 | }; |
| 5907 | 6041 | arg_val.hash(arg_ty, &hasher, mod); |
| 5908 | 6042 | if (is_anytype) { |
| 5909 | 6043 | arg_ty.hashWithHasher(&hasher, mod); |
| ... | ... | @@ -6059,19 +6193,18 @@ fn instantiateGenericCall( |
| 6059 | 6193 | }, |
| 6060 | 6194 | else => continue, |
| 6061 | 6195 | } |
| 6062 | | const arg_src = call_src; // TODO: better source location |
| 6063 | 6196 | const arg = uncasted_args[arg_i]; |
| 6064 | 6197 | if (is_comptime) { |
| 6065 | | if (try sema.resolveMaybeUndefVal(block, arg_src, arg)) |arg_val| { |
| 6198 | if (try sema.resolveMaybeUndefVal(block, .unneeded, arg)) |arg_val| { |
| 6066 | 6199 | const child_arg = try child_sema.addConstant(sema.typeOf(arg), arg_val); |
| 6067 | 6200 | child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg); |
| 6068 | 6201 | } else { |
| 6069 | | return sema.failWithNeededComptime(block, arg_src); |
| 6202 | return sema.failWithNeededComptime(block, .unneeded, undefined); |
| 6070 | 6203 | } |
| 6071 | 6204 | } else if (is_anytype) { |
| 6072 | 6205 | const arg_ty = sema.typeOf(arg); |
| 6073 | | if (try sema.typeRequiresComptime(block, arg_src, arg_ty)) { |
| 6074 | | const arg_val = try sema.resolveConstValue(block, arg_src, arg); |
| 6206 | if (try sema.typeRequiresComptime(block, .unneeded, arg_ty)) { |
| 6207 | const arg_val = try sema.resolveConstValue(block, .unneeded, arg, undefined); |
| 6075 | 6208 | const child_arg = try child_sema.addConstant(arg_ty, arg_val); |
| 6076 | 6209 | child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg); |
| 6077 | 6210 | } else { |
| ... | ... | @@ -6093,7 +6226,7 @@ fn instantiateGenericCall( |
| 6093 | 6226 | } |
| 6094 | 6227 | return err; |
| 6095 | 6228 | }; |
| 6096 | | const new_func_val = child_sema.resolveConstValue(&child_block, .unneeded, new_func_inst) catch unreachable; |
| 6229 | const new_func_val = child_sema.resolveConstValue(&child_block, .unneeded, new_func_inst, undefined) catch unreachable; |
| 6097 | 6230 | const new_func = new_func_val.castTag(.function).?.data; |
| 6098 | 6231 | errdefer new_func.deinit(gpa); |
| 6099 | 6232 | assert(new_func == new_module_func); |
| ... | ... | @@ -6129,8 +6262,7 @@ fn instantiateGenericCall( |
| 6129 | 6262 | const copied_arg_ty = try child_sema.typeOf(arg).copy(new_decl_arena_allocator); |
| 6130 | 6263 | anytype_args[arg_i] = is_anytype; |
| 6131 | 6264 | |
| 6132 | | const arg_src = call_src; // TODO: better source location |
| 6133 | | if (try sema.typeRequiresComptime(block, arg_src, copied_arg_ty)) { |
| 6265 | if (try sema.typeRequiresComptime(block, .unneeded, copied_arg_ty)) { |
| 6134 | 6266 | is_comptime = true; |
| 6135 | 6267 | } |
| 6136 | 6268 | |
| ... | ... | @@ -6195,7 +6327,7 @@ fn instantiateGenericCall( |
| 6195 | 6327 | const callee_inst = try sema.analyzeDeclVal(block, func_src, callee.owner_decl); |
| 6196 | 6328 | |
| 6197 | 6329 | // Make a runtime call to the new function, making sure to omit the comptime args. |
| 6198 | | try sema.requireRuntimeBlock(block, call_src); |
| 6330 | try sema.requireFunctionBlock(block, call_src); |
| 6199 | 6331 | |
| 6200 | 6332 | const comptime_args = callee.comptime_args.?; |
| 6201 | 6333 | const new_fn_info = mod.declPtr(callee.owner_decl).ty.fnInfo(); |
| ... | ... | @@ -6209,18 +6341,30 @@ fn instantiateGenericCall( |
| 6209 | 6341 | .param_comptime, .param_anytype_comptime, .param, .param_anytype => {}, |
| 6210 | 6342 | else => continue, |
| 6211 | 6343 | } |
| 6212 | | const arg_src = call_src; // TODO: better source location |
| 6213 | | const is_runtime = comptime_args[total_i].val.tag() == .generic_poison and |
| 6214 | | comptime_args[total_i].ty.hasRuntimeBits() and |
| 6215 | | !(try sema.typeRequiresComptime(block, arg_src, comptime_args[total_i].ty)); |
| 6216 | | if (is_runtime) { |
| 6217 | | const param_ty = new_fn_info.param_types[runtime_i]; |
| 6218 | | const uncasted_arg = uncasted_args[total_i]; |
| 6219 | | const casted_arg = try sema.coerce(block, param_ty, uncasted_arg, arg_src); |
| 6220 | | try sema.queueFullTypeResolution(param_ty); |
| 6221 | | runtime_args[runtime_i] = casted_arg; |
| 6222 | | runtime_i += 1; |
| 6223 | | } |
| 6344 | sema.analyzeGenericCallArg( |
| 6345 | block, |
| 6346 | .unneeded, |
| 6347 | uncasted_args[total_i], |
| 6348 | comptime_args[total_i], |
| 6349 | runtime_args, |
| 6350 | new_fn_info, |
| 6351 | &runtime_i, |
| 6352 | ) catch |err| switch (err) { |
| 6353 | error.NeededSourceLocation => { |
| 6354 | const decl = sema.mod.declPtr(block.src_decl); |
| 6355 | _ = try sema.analyzeGenericCallArg( |
| 6356 | block, |
| 6357 | Module.argSrc(call_src.node_offset.x, sema.gpa, decl, total_i), |
| 6358 | uncasted_args[total_i], |
| 6359 | comptime_args[total_i], |
| 6360 | runtime_args, |
| 6361 | new_fn_info, |
| 6362 | &runtime_i, |
| 6363 | ); |
| 6364 | return error.AnalysisFail; |
| 6365 | }, |
| 6366 | else => |e| return e, |
| 6367 | }; |
| 6224 | 6368 | total_i += 1; |
| 6225 | 6369 | } |
| 6226 | 6370 | |
| ... | ... | @@ -6314,7 +6458,7 @@ fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 6314 | 6458 | const elem_type_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 6315 | 6459 | const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; |
| 6316 | 6460 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 6317 | | const len = try sema.resolveInt(block, len_src, extra.lhs, Type.u32); |
| 6461 | const len = try sema.resolveInt(block, len_src, extra.lhs, Type.u32, "vector length must be comptime known"); |
| 6318 | 6462 | const elem_type = try sema.resolveType(block, elem_type_src, extra.rhs); |
| 6319 | 6463 | try sema.checkVectorElemType(block, elem_type_src, elem_type); |
| 6320 | 6464 | const vector_type = try Type.Tag.vector.create(sema.arena, .{ |
| ... | ... | @@ -6332,7 +6476,7 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 6332 | 6476 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 6333 | 6477 | const len_src: LazySrcLoc = .{ .node_offset_array_type_len = inst_data.src_node }; |
| 6334 | 6478 | const elem_src: LazySrcLoc = .{ .node_offset_array_type_elem = inst_data.src_node }; |
| 6335 | | const len = try sema.resolveInt(block, len_src, extra.lhs, Type.usize); |
| 6479 | const len = try sema.resolveInt(block, len_src, extra.lhs, Type.usize, "array length must be comptime known"); |
| 6336 | 6480 | const elem_type = try sema.resolveType(block, elem_src, extra.rhs); |
| 6337 | 6481 | const array_ty = try Type.array(sema.arena, len, null, elem_type, sema.mod); |
| 6338 | 6482 | |
| ... | ... | @@ -6348,11 +6492,11 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil |
| 6348 | 6492 | const len_src: LazySrcLoc = .{ .node_offset_array_type_len = inst_data.src_node }; |
| 6349 | 6493 | const sentinel_src: LazySrcLoc = .{ .node_offset_array_type_sentinel = inst_data.src_node }; |
| 6350 | 6494 | const elem_src: LazySrcLoc = .{ .node_offset_array_type_elem = inst_data.src_node }; |
| 6351 | | const len = try sema.resolveInt(block, len_src, extra.len, Type.usize); |
| 6495 | const len = try sema.resolveInt(block, len_src, extra.len, Type.usize, "array length must be comptime known"); |
| 6352 | 6496 | const elem_type = try sema.resolveType(block, elem_src, extra.elem_type); |
| 6353 | 6497 | const uncasted_sentinel = try sema.resolveInst(extra.sentinel); |
| 6354 | 6498 | const sentinel = try sema.coerce(block, elem_type, uncasted_sentinel, sentinel_src); |
| 6355 | | const sentinel_val = try sema.resolveConstValue(block, sentinel_src, sentinel); |
| 6499 | const sentinel_val = try sema.resolveConstValue(block, sentinel_src, sentinel, "array sentinel value must be comptime known"); |
| 6356 | 6500 | const array_ty = try Type.array(sema.arena, len, sentinel_val, elem_type, sema.mod); |
| 6357 | 6501 | |
| 6358 | 6502 | return sema.addType(array_ty); |
| ... | ... | @@ -6452,7 +6596,7 @@ fn zirErrorToInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat |
| 6452 | 6596 | } |
| 6453 | 6597 | } |
| 6454 | 6598 | |
| 6455 | | try sema.requireRuntimeBlock(block, src); |
| 6599 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 6456 | 6600 | return block.addBitCast(result_ty, operand); |
| 6457 | 6601 | } |
| 6458 | 6602 | |
| ... | ... | @@ -6478,7 +6622,7 @@ fn zirIntToError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat |
| 6478 | 6622 | }; |
| 6479 | 6623 | return sema.addConstant(Type.anyerror, Value.initPayload(&payload.base)); |
| 6480 | 6624 | } |
| 6481 | | try sema.requireRuntimeBlock(block, src); |
| 6625 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 6482 | 6626 | if (block.wantSafety()) { |
| 6483 | 6627 | const is_lt_len = try block.addUnOp(.cmp_lt_errors_len, operand); |
| 6484 | 6628 | try sema.addSafetyCheck(block, is_lt_len, .invalid_error_code); |
| ... | ... | @@ -6598,7 +6742,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 6598 | 6742 | return sema.addConstant(int_tag_ty, try val.copy(sema.arena)); |
| 6599 | 6743 | } |
| 6600 | 6744 | |
| 6601 | | try sema.requireRuntimeBlock(block, src); |
| 6745 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 6602 | 6746 | return block.addBitCast(int_tag_ty, enum_tag); |
| 6603 | 6747 | } |
| 6604 | 6748 | |
| ... | ... | @@ -6645,7 +6789,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 6645 | 6789 | return sema.addConstant(dest_ty, int_val); |
| 6646 | 6790 | } |
| 6647 | 6791 | |
| 6648 | | try sema.requireRuntimeBlock(block, src); |
| 6792 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 6649 | 6793 | // TODO insert safety check to make sure the value matches an enum value |
| 6650 | 6794 | return block.addTyOp(.intcast, dest_ty, operand); |
| 6651 | 6795 | } |
| ... | ... | @@ -6696,7 +6840,7 @@ fn analyzeOptionalPayloadPtr( |
| 6696 | 6840 | // If the pointer resulting from this function was stored at comptime, |
| 6697 | 6841 | // the optional non-null bit would be set that way. But in this case, |
| 6698 | 6842 | // we need to emit a runtime instruction to do it. |
| 6699 | | try sema.requireRuntimeBlock(block, src); |
| 6843 | try sema.requireFunctionBlock(block, src); |
| 6700 | 6844 | _ = try block.addTyOp(.optional_payload_ptr_set, child_pointer, optional_ptr); |
| 6701 | 6845 | } |
| 6702 | 6846 | return sema.addConstant( |
| ... | ... | @@ -6722,7 +6866,7 @@ fn analyzeOptionalPayloadPtr( |
| 6722 | 6866 | } |
| 6723 | 6867 | } |
| 6724 | 6868 | |
| 6725 | | try sema.requireRuntimeBlock(block, src); |
| 6869 | try sema.requireRuntimeBlock(block, src, null); |
| 6726 | 6870 | if (safety_check and block.wantSafety()) { |
| 6727 | 6871 | const is_non_null = try block.addUnOp(.is_non_null_ptr, optional_ptr); |
| 6728 | 6872 | try sema.addSafetyCheck(block, is_non_null, .unwrap_null); |
| ... | ... | @@ -6778,7 +6922,7 @@ fn zirOptionalPayload( |
| 6778 | 6922 | return sema.addConstant(result_ty, val); |
| 6779 | 6923 | } |
| 6780 | 6924 | |
| 6781 | | try sema.requireRuntimeBlock(block, src); |
| 6925 | try sema.requireRuntimeBlock(block, src, null); |
| 6782 | 6926 | if (safety_check and block.wantSafety()) { |
| 6783 | 6927 | const is_non_null = try block.addUnOp(.is_non_null, operand); |
| 6784 | 6928 | try sema.addSafetyCheck(block, is_non_null, .unwrap_null); |
| ... | ... | @@ -6827,7 +6971,7 @@ fn analyzeErrUnionPayload( |
| 6827 | 6971 | return sema.addConstant(payload_ty, data); |
| 6828 | 6972 | } |
| 6829 | 6973 | |
| 6830 | | try sema.requireRuntimeBlock(block, src); |
| 6974 | try sema.requireRuntimeBlock(block, src, null); |
| 6831 | 6975 | |
| 6832 | 6976 | // If the error set has no fields then no safety check is needed. |
| 6833 | 6977 | if (safety_check and block.wantSafety() and |
| ... | ... | @@ -6887,7 +7031,7 @@ fn analyzeErrUnionPayloadPtr( |
| 6887 | 7031 | // If the pointer resulting from this function was stored at comptime, |
| 6888 | 7032 | // the error union error code would be set that way. But in this case, |
| 6889 | 7033 | // we need to emit a runtime instruction to do it. |
| 6890 | | try sema.requireRuntimeBlock(block, src); |
| 7034 | try sema.requireRuntimeBlock(block, src, null); |
| 6891 | 7035 | _ = try block.addTyOp(.errunion_payload_ptr_set, operand_pointer_ty, operand); |
| 6892 | 7036 | } |
| 6893 | 7037 | return sema.addConstant( |
| ... | ... | @@ -6913,7 +7057,7 @@ fn analyzeErrUnionPayloadPtr( |
| 6913 | 7057 | } |
| 6914 | 7058 | } |
| 6915 | 7059 | |
| 6916 | | try sema.requireRuntimeBlock(block, src); |
| 7060 | try sema.requireRuntimeBlock(block, src, null); |
| 6917 | 7061 | |
| 6918 | 7062 | // If the error set has no fields then no safety check is needed. |
| 6919 | 7063 | if (safety_check and block.wantSafety() and |
| ... | ... | @@ -6951,7 +7095,7 @@ fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 6951 | 7095 | return sema.addConstant(result_ty, val); |
| 6952 | 7096 | } |
| 6953 | 7097 | |
| 6954 | | try sema.requireRuntimeBlock(block, src); |
| 7098 | try sema.requireRuntimeBlock(block, src, null); |
| 6955 | 7099 | return block.addTyOp(.unwrap_errunion_err, result_ty, operand); |
| 6956 | 7100 | } |
| 6957 | 7101 | |
| ... | ... | @@ -6981,7 +7125,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 6981 | 7125 | } |
| 6982 | 7126 | } |
| 6983 | 7127 | |
| 6984 | | try sema.requireRuntimeBlock(block, src); |
| 7128 | try sema.requireRuntimeBlock(block, src, null); |
| 6985 | 7129 | return block.addTyOp(.unwrap_errunion_err_ptr, result_ty, operand); |
| 6986 | 7130 | } |
| 6987 | 7131 | |
| ... | ... | @@ -7037,7 +7181,7 @@ fn zirFunc( |
| 7037 | 7181 | const ret_ty_body = sema.code.extra[extra_index..][0..extra.data.ret_body_len]; |
| 7038 | 7182 | extra_index += ret_ty_body.len; |
| 7039 | 7183 | |
| 7040 | | const ret_ty_val = try sema.resolveGenericBody(block, ret_ty_src, ret_ty_body, inst, Type.type); |
| 7184 | const ret_ty_val = try sema.resolveGenericBody(block, ret_ty_src, ret_ty_body, inst, Type.type, "return type must be comptime known"); |
| 7041 | 7185 | var buffer: Value.ToTypeBuffer = undefined; |
| 7042 | 7186 | break :blk try ret_ty_val.toType(&buffer).copy(sema.arena); |
| 7043 | 7187 | }, |
| ... | ... | @@ -7085,6 +7229,7 @@ fn resolveGenericBody( |
| 7085 | 7229 | body: []const Zir.Inst.Index, |
| 7086 | 7230 | func_inst: Zir.Inst.Index, |
| 7087 | 7231 | dest_ty: Type, |
| 7232 | reason: []const u8, |
| 7088 | 7233 | ) !Value { |
| 7089 | 7234 | assert(body.len != 0); |
| 7090 | 7235 | |
| ... | ... | @@ -7098,7 +7243,7 @@ fn resolveGenericBody( |
| 7098 | 7243 | } |
| 7099 | 7244 | const uncasted = sema.resolveBody(block, body, func_inst) catch |err| break :err err; |
| 7100 | 7245 | const result = sema.coerce(block, dest_ty, uncasted, src) catch |err| break :err err; |
| 7101 | | const val = sema.resolveConstValue(block, src, result) catch |err| break :err err; |
| 7246 | const val = sema.resolveConstValue(block, src, result, reason) catch |err| break :err err; |
| 7102 | 7247 | return val; |
| 7103 | 7248 | }; |
| 7104 | 7249 | switch (err) { |
| ... | ... | @@ -7205,6 +7350,7 @@ fn funcCommon( |
| 7205 | 7350 | opt_lib_name: ?[]const u8, |
| 7206 | 7351 | noalias_bits: u32, |
| 7207 | 7352 | ) CompileError!Air.Inst.Ref { |
| 7353 | const fn_src = LazySrcLoc.nodeOffset(src_node_offset); |
| 7208 | 7354 | const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = src_node_offset }; |
| 7209 | 7355 | const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = src_node_offset }; |
| 7210 | 7356 | |
| ... | ... | @@ -7213,10 +7359,6 @@ fn funcCommon( |
| 7213 | 7359 | address_space == null or |
| 7214 | 7360 | section == .generic or |
| 7215 | 7361 | cc == null; |
| 7216 | | // Check for generic params. |
| 7217 | | for (block.params.items) |param| { |
| 7218 | | if (param.ty.tag() == .generic_poison) is_generic = true; |
| 7219 | | } |
| 7220 | 7362 | |
| 7221 | 7363 | var destroy_fn_on_error = false; |
| 7222 | 7364 | const new_func: *Module.Fn = new_func: { |
| ... | ... | @@ -7227,7 +7369,10 @@ fn funcCommon( |
| 7227 | 7369 | break :new_func new_func; |
| 7228 | 7370 | } |
| 7229 | 7371 | destroy_fn_on_error = true; |
| 7230 | | break :new_func try sema.gpa.create(Module.Fn); |
| 7372 | const new_func = try sema.gpa.create(Module.Fn); |
| 7373 | // Set this here so that the inferred return type can be printed correctly if it appears in an error. |
| 7374 | new_func.owner_decl = sema.owner_decl_index; |
| 7375 | break :new_func new_func; |
| 7231 | 7376 | }; |
| 7232 | 7377 | errdefer if (destroy_fn_on_error) sema.gpa.destroy(new_func); |
| 7233 | 7378 | |
| ... | ... | @@ -7261,18 +7406,47 @@ fn funcCommon( |
| 7261 | 7406 | } |
| 7262 | 7407 | } |
| 7263 | 7408 | |
| 7409 | // These locals are pulled out from the init expression below to work around |
| 7410 | // a stage1 compiler bug. |
| 7411 | // In the case of generic calling convention, or generic alignment, we use |
| 7412 | // default values which are only meaningful for the generic function, *not* |
| 7413 | // the instantiation, which can depend on comptime parameters. |
| 7414 | // Related proposal: https://github.com/ziglang/zig/issues/11834 |
| 7415 | const cc_workaround = cc orelse .Unspecified; |
| 7416 | const align_workaround = alignment orelse 0; |
| 7417 | |
| 7264 | 7418 | const param_types = try sema.arena.alloc(Type, block.params.items.len); |
| 7265 | 7419 | const comptime_params = try sema.arena.alloc(bool, block.params.items.len); |
| 7266 | 7420 | for (block.params.items) |param, i| { |
| 7267 | | const param_src = LazySrcLoc.nodeOffset(src_node_offset); // TODO better soruce location |
| 7268 | 7421 | param_types[i] = param.ty; |
| 7269 | | comptime_params[i] = param.is_comptime or |
| 7270 | | try sema.typeRequiresComptime(block, param_src, param.ty); |
| 7271 | | is_generic = is_generic or comptime_params[i] or param.ty.tag() == .generic_poison; |
| 7272 | | if (is_extern and is_generic) { |
| 7273 | | // TODO add note: function is generic because of this parameter |
| 7274 | | return sema.fail(block, param_src, "extern function cannot be generic", .{}); |
| 7275 | | } |
| 7422 | sema.analyzeParameter( |
| 7423 | block, |
| 7424 | fn_src, |
| 7425 | .unneeded, |
| 7426 | param, |
| 7427 | comptime_params, |
| 7428 | i, |
| 7429 | &is_generic, |
| 7430 | is_extern, |
| 7431 | cc_workaround, |
| 7432 | ) catch |err| switch (err) { |
| 7433 | error.NeededSourceLocation => { |
| 7434 | const decl = sema.mod.declPtr(block.src_decl); |
| 7435 | try sema.analyzeParameter( |
| 7436 | block, |
| 7437 | fn_src, |
| 7438 | Module.paramSrc(src_node_offset, sema.gpa, decl, i), |
| 7439 | param, |
| 7440 | comptime_params, |
| 7441 | i, |
| 7442 | &is_generic, |
| 7443 | is_extern, |
| 7444 | cc_workaround, |
| 7445 | ); |
| 7446 | return error.AnalysisFail; |
| 7447 | }, |
| 7448 | else => |e| return e, |
| 7449 | }; |
| 7276 | 7450 | } |
| 7277 | 7451 | |
| 7278 | 7452 | const ret_poison = if (!is_generic) rp: { |
| ... | ... | @@ -7302,14 +7476,34 @@ fn funcCommon( |
| 7302 | 7476 | }); |
| 7303 | 7477 | }; |
| 7304 | 7478 | |
| 7305 | | // These locals are pulled out from the init expression below to work around |
| 7306 | | // a stage1 compiler bug. |
| 7307 | | // In the case of generic calling convention, or generic alignment, we use |
| 7308 | | // default values which are only meaningful for the generic function, *not* |
| 7309 | | // the instantiation, which can depend on comptime parameters. |
| 7310 | | // Related proposal: https://github.com/ziglang/zig/issues/11834 |
| 7311 | | const cc_workaround = cc orelse .Unspecified; |
| 7312 | | const align_workaround = alignment orelse 0; |
| 7479 | if (!bare_return_type.isValidReturnType()) { |
| 7480 | const opaque_str = if (bare_return_type.zigTypeTag() == .Opaque) "opaque " else ""; |
| 7481 | const msg = msg: { |
| 7482 | const msg = try sema.errMsg(block, ret_ty_src, "{s}return type '{}' not allowed", .{ |
| 7483 | opaque_str, bare_return_type.fmt(sema.mod), |
| 7484 | }); |
| 7485 | errdefer msg.destroy(sema.gpa); |
| 7486 | |
| 7487 | try sema.addDeclaredHereNote(msg, bare_return_type); |
| 7488 | break :msg msg; |
| 7489 | }; |
| 7490 | return sema.failWithOwnedErrorMsg(block, msg); |
| 7491 | } |
| 7492 | if (!Type.fnCallingConventionAllowsZigTypes(cc_workaround) and !(try sema.validateExternType(return_type, .ret_ty))) { |
| 7493 | const msg = msg: { |
| 7494 | const msg = try sema.errMsg(block, ret_ty_src, "return type '{}' not allowed in function with calling convention '{s}'", .{ |
| 7495 | return_type.fmt(sema.mod), @tagName(cc_workaround), |
| 7496 | }); |
| 7497 | errdefer msg.destroy(sema.gpa); |
| 7498 | |
| 7499 | const src_decl = sema.mod.declPtr(block.src_decl); |
| 7500 | try sema.explainWhyTypeIsNotExtern(block, ret_ty_src, msg, ret_ty_src.toSrcLoc(src_decl), return_type, .ret_ty); |
| 7501 | |
| 7502 | try sema.addDeclaredHereNote(msg, return_type); |
| 7503 | break :msg msg; |
| 7504 | }; |
| 7505 | return sema.failWithOwnedErrorMsg(block, msg); |
| 7506 | } |
| 7313 | 7507 | |
| 7314 | 7508 | const arch = sema.mod.getTarget().cpu.arch; |
| 7315 | 7509 | if (switch (cc_workaround) { |
| ... | ... | @@ -7442,6 +7636,79 @@ fn funcCommon( |
| 7442 | 7636 | return sema.addConstant(fn_ty, Value.initPayload(&fn_payload.base)); |
| 7443 | 7637 | } |
| 7444 | 7638 | |
| 7639 | fn analyzeParameter( |
| 7640 | sema: *Sema, |
| 7641 | block: *Block, |
| 7642 | func_src: LazySrcLoc, |
| 7643 | param_src: LazySrcLoc, |
| 7644 | param: Block.Param, |
| 7645 | comptime_params: []bool, |
| 7646 | i: usize, |
| 7647 | is_generic: *bool, |
| 7648 | is_extern: bool, |
| 7649 | cc: std.builtin.CallingConvention, |
| 7650 | ) !void { |
| 7651 | const requires_comptime = try sema.typeRequiresComptime(block, param_src, param.ty); |
| 7652 | comptime_params[i] = param.is_comptime or requires_comptime; |
| 7653 | const this_generic = comptime_params[i] or param.ty.tag() == .generic_poison; |
| 7654 | is_generic.* = is_generic.* or this_generic; |
| 7655 | if (is_extern and this_generic) { |
| 7656 | // TODO this check should exist somewhere for notes. |
| 7657 | if (param_src == .unneeded) return error.NeededSourceLocation; |
| 7658 | const msg = msg: { |
| 7659 | const msg = try sema.errMsg(block, func_src, "extern function cannot be generic", .{}); |
| 7660 | errdefer msg.destroy(sema.gpa); |
| 7661 | |
| 7662 | try sema.errNote(block, param_src, msg, "function is generic because of this parameter", .{}); |
| 7663 | break :msg msg; |
| 7664 | }; |
| 7665 | return sema.failWithOwnedErrorMsg(block, msg); |
| 7666 | } |
| 7667 | if (this_generic and !Type.fnCallingConventionAllowsZigTypes(cc)) { |
| 7668 | return sema.fail(block, param_src, "generic parameters not allowed in function with calling convention '{s}'", .{@tagName(cc)}); |
| 7669 | } |
| 7670 | if (!param.ty.isValidParamType()) { |
| 7671 | const opaque_str = if (param.ty.zigTypeTag() == .Opaque) "opaque " else ""; |
| 7672 | const msg = msg: { |
| 7673 | const msg = try sema.errMsg(block, param_src, "parameter of {s}type '{}' not allowed", .{ |
| 7674 | opaque_str, param.ty.fmt(sema.mod), |
| 7675 | }); |
| 7676 | errdefer msg.destroy(sema.gpa); |
| 7677 | |
| 7678 | try sema.addDeclaredHereNote(msg, param.ty); |
| 7679 | break :msg msg; |
| 7680 | }; |
| 7681 | return sema.failWithOwnedErrorMsg(block, msg); |
| 7682 | } |
| 7683 | if (!Type.fnCallingConventionAllowsZigTypes(cc) and !(try sema.validateExternType(param.ty, .param_ty))) { |
| 7684 | const msg = msg: { |
| 7685 | const msg = try sema.errMsg(block, param_src, "parameter of type '{}' not allowed in function with calling convention '{s}'", .{ |
| 7686 | param.ty.fmt(sema.mod), @tagName(cc), |
| 7687 | }); |
| 7688 | errdefer msg.destroy(sema.gpa); |
| 7689 | |
| 7690 | const src_decl = sema.mod.declPtr(block.src_decl); |
| 7691 | try sema.explainWhyTypeIsNotExtern(block, param_src, msg, param_src.toSrcLoc(src_decl), param.ty, .param_ty); |
| 7692 | |
| 7693 | try sema.addDeclaredHereNote(msg, param.ty); |
| 7694 | break :msg msg; |
| 7695 | }; |
| 7696 | return sema.failWithOwnedErrorMsg(block, msg); |
| 7697 | } |
| 7698 | if (requires_comptime and !param.is_comptime) { |
| 7699 | const msg = msg: { |
| 7700 | const msg = try sema.errMsg(block, param_src, "parametter of type '{}' must be declared comptime", .{ |
| 7701 | param.ty.fmt(sema.mod), |
| 7702 | }); |
| 7703 | errdefer msg.destroy(sema.gpa); |
| 7704 | |
| 7705 | try sema.addDeclaredHereNote(msg, param.ty); |
| 7706 | break :msg msg; |
| 7707 | }; |
| 7708 | return sema.failWithOwnedErrorMsg(block, msg); |
| 7709 | } |
| 7710 | } |
| 7711 | |
| 7445 | 7712 | fn zirParam( |
| 7446 | 7713 | sema: *Sema, |
| 7447 | 7714 | block: *Block, |
| ... | ... | @@ -7629,7 +7896,7 @@ fn zirPtrToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 7629 | 7896 | if (try sema.resolveMaybeUndefVal(block, ptr_src, ptr)) |ptr_val| { |
| 7630 | 7897 | return sema.addConstant(Type.usize, ptr_val); |
| 7631 | 7898 | } |
| 7632 | | try sema.requireRuntimeBlock(block, ptr_src); |
| 7899 | try sema.requireRuntimeBlock(block, ptr_src, ptr_src); |
| 7633 | 7900 | return block.addUnOp(.ptrtoint, ptr); |
| 7634 | 7901 | } |
| 7635 | 7902 | |
| ... | ... | @@ -7681,7 +7948,7 @@ fn zirFieldValNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr |
| 7681 | 7948 | const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; |
| 7682 | 7949 | const extra = sema.code.extraData(Zir.Inst.FieldNamed, inst_data.payload_index).data; |
| 7683 | 7950 | const object = try sema.resolveInst(extra.lhs); |
| 7684 | | const field_name = try sema.resolveConstString(block, field_name_src, extra.field_name); |
| 7951 | const field_name = try sema.resolveConstString(block, field_name_src, extra.field_name, "field name must be comptime known"); |
| 7685 | 7952 | return sema.fieldVal(block, src, object, field_name, field_name_src); |
| 7686 | 7953 | } |
| 7687 | 7954 | |
| ... | ... | @@ -7694,7 +7961,7 @@ fn zirFieldPtrNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr |
| 7694 | 7961 | const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; |
| 7695 | 7962 | const extra = sema.code.extraData(Zir.Inst.FieldNamed, inst_data.payload_index).data; |
| 7696 | 7963 | const object_ptr = try sema.resolveInst(extra.lhs); |
| 7697 | | const field_name = try sema.resolveConstString(block, field_name_src, extra.field_name); |
| 7964 | const field_name = try sema.resolveConstString(block, field_name_src, extra.field_name, "field name must be comptime known"); |
| 7698 | 7965 | return sema.fieldPtr(block, src, object_ptr, field_name, field_name_src); |
| 7699 | 7966 | } |
| 7700 | 7967 | |
| ... | ... | @@ -7706,7 +7973,7 @@ fn zirFieldCallBindNamed(sema: *Sema, block: *Block, extended: Zir.Inst.Extended |
| 7706 | 7973 | const src = LazySrcLoc.nodeOffset(extra.node); |
| 7707 | 7974 | const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node }; |
| 7708 | 7975 | const object_ptr = try sema.resolveInst(extra.lhs); |
| 7709 | | const field_name = try sema.resolveConstString(block, field_name_src, extra.field_name); |
| 7976 | const field_name = try sema.resolveConstString(block, field_name_src, extra.field_name, "field name must be comptime known"); |
| 7710 | 7977 | return sema.fieldCallBind(block, src, object_ptr, field_name, field_name_src); |
| 7711 | 7978 | } |
| 7712 | 7979 | |
| ... | ... | @@ -7722,12 +7989,13 @@ fn zirIntCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 7722 | 7989 | const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs); |
| 7723 | 7990 | const operand = try sema.resolveInst(extra.rhs); |
| 7724 | 7991 | |
| 7725 | | return sema.intCast(block, dest_ty, dest_ty_src, operand, operand_src, true); |
| 7992 | return sema.intCast(block, inst_data.src(), dest_ty, dest_ty_src, operand, operand_src, true); |
| 7726 | 7993 | } |
| 7727 | 7994 | |
| 7728 | 7995 | fn intCast( |
| 7729 | 7996 | sema: *Sema, |
| 7730 | 7997 | block: *Block, |
| 7998 | src: LazySrcLoc, |
| 7731 | 7999 | dest_ty: Type, |
| 7732 | 8000 | dest_ty_src: LazySrcLoc, |
| 7733 | 8001 | operand: Air.Inst.Ref, |
| ... | ... | @@ -7750,7 +8018,7 @@ fn intCast( |
| 7750 | 8018 | if ((try sema.typeHasOnePossibleValue(block, dest_ty_src, dest_ty))) |opv| { |
| 7751 | 8019 | // requirement: intCast(u0, input) iff input == 0 |
| 7752 | 8020 | if (runtime_safety and block.wantSafety()) { |
| 7753 | | try sema.requireRuntimeBlock(block, operand_src); |
| 8021 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 7754 | 8022 | const target = sema.mod.getTarget(); |
| 7755 | 8023 | const wanted_info = dest_scalar_ty.intInfo(target); |
| 7756 | 8024 | const wanted_bits = wanted_info.bits; |
| ... | ... | @@ -7765,7 +8033,7 @@ fn intCast( |
| 7765 | 8033 | return sema.addConstant(dest_ty, opv); |
| 7766 | 8034 | } |
| 7767 | 8035 | |
| 7768 | | try sema.requireRuntimeBlock(block, operand_src); |
| 8036 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 7769 | 8037 | if (runtime_safety and block.wantSafety()) { |
| 7770 | 8038 | const target = sema.mod.getTarget(); |
| 7771 | 8039 | const actual_info = operand_scalar_ty.intInfo(target); |
| ... | ... | @@ -7972,7 +8240,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 7972 | 8240 | if (dst_bits >= src_bits) { |
| 7973 | 8241 | return sema.coerce(block, dest_ty, operand, operand_src); |
| 7974 | 8242 | } |
| 7975 | | try sema.requireRuntimeBlock(block, operand_src); |
| 8243 | try sema.requireRuntimeBlock(block, inst_data.src(), operand_src); |
| 7976 | 8244 | return block.addTyOp(.fptrunc, dest_ty, operand); |
| 7977 | 8245 | } |
| 7978 | 8246 | |
| ... | ... | @@ -8096,7 +8364,6 @@ fn zirSwitchCapture( |
| 8096 | 8364 | const switch_info = zir_datas[capture_info.switch_inst].pl_node; |
| 8097 | 8365 | const switch_extra = sema.code.extraData(Zir.Inst.SwitchBlock, switch_info.payload_index); |
| 8098 | 8366 | const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = switch_info.src_node }; |
| 8099 | | const switch_src = switch_info.src(); |
| 8100 | 8367 | const operand_is_ref = switch_extra.data.bits.is_ref; |
| 8101 | 8368 | const cond_inst = Zir.refToIndex(switch_extra.data.operand).?; |
| 8102 | 8369 | const cond_info = sema.code.instructions.items(.data)[cond_inst].un_node; |
| ... | ... | @@ -8141,24 +8408,30 @@ fn zirSwitchCapture( |
| 8141 | 8408 | |
| 8142 | 8409 | const first_item = try sema.resolveInst(items[0]); |
| 8143 | 8410 | // Previous switch validation ensured this will succeed |
| 8144 | | const first_item_val = sema.resolveConstValue(block, .unneeded, first_item) catch unreachable; |
| 8411 | const first_item_val = sema.resolveConstValue(block, .unneeded, first_item, undefined) catch unreachable; |
| 8145 | 8412 | |
| 8146 | 8413 | const first_field_index = @intCast(u32, enum_ty.enumTagFieldIndex(first_item_val, sema.mod).?); |
| 8147 | 8414 | const first_field = union_obj.fields.values()[first_field_index]; |
| 8148 | 8415 | |
| 8149 | | for (items[1..]) |item| { |
| 8416 | for (items[1..]) |item, i| { |
| 8150 | 8417 | const item_ref = try sema.resolveInst(item); |
| 8151 | 8418 | // Previous switch validation ensured this will succeed |
| 8152 | | const item_val = sema.resolveConstValue(block, .unneeded, item_ref) catch unreachable; |
| 8419 | const item_val = sema.resolveConstValue(block, .unneeded, item_ref, undefined) catch unreachable; |
| 8153 | 8420 | |
| 8154 | 8421 | const field_index = enum_ty.enumTagFieldIndex(item_val, sema.mod).?; |
| 8155 | 8422 | const field = union_obj.fields.values()[field_index]; |
| 8156 | 8423 | if (!field.ty.eql(first_field.ty, sema.mod)) { |
| 8157 | | const first_item_src = switch_src; // TODO better source location |
| 8158 | | const item_src = switch_src; |
| 8159 | 8424 | const msg = msg: { |
| 8160 | | const msg = try sema.errMsg(block, switch_src, "capture group with incompatible types", .{}); |
| 8425 | const raw_capture_src = Module.SwitchProngSrc{ .multi_capture = capture_info.prong_index }; |
| 8426 | const capture_src = raw_capture_src.resolve(sema.gpa, sema.mod.declPtr(block.src_decl), switch_info.src_node, .first); |
| 8427 | |
| 8428 | const msg = try sema.errMsg(block, capture_src, "capture group with incompatible types", .{}); |
| 8161 | 8429 | errdefer msg.destroy(sema.gpa); |
| 8430 | |
| 8431 | const raw_first_item_src = Module.SwitchProngSrc{ .multi = .{ .prong = capture_info.prong_index, .item = 0 } }; |
| 8432 | const first_item_src = raw_first_item_src.resolve(sema.gpa, sema.mod.declPtr(block.src_decl), switch_info.src_node, .first); |
| 8433 | const raw_item_src = Module.SwitchProngSrc{ .multi = .{ .prong = capture_info.prong_index, .item = 1 + @intCast(u32, i) } }; |
| 8434 | const item_src = raw_item_src.resolve(sema.gpa, sema.mod.declPtr(block.src_decl), switch_info.src_node, .first); |
| 8162 | 8435 | try sema.errNote(block, first_item_src, msg, "type '{}' here", .{first_field.ty.fmt(sema.mod)}); |
| 8163 | 8436 | try sema.errNote(block, item_src, msg, "type '{}' here", .{field.ty.fmt(sema.mod)}); |
| 8164 | 8437 | break :msg msg; |
| ... | ... | @@ -8186,7 +8459,7 @@ fn zirSwitchCapture( |
| 8186 | 8459 | }), |
| 8187 | 8460 | ); |
| 8188 | 8461 | } |
| 8189 | | try sema.requireRuntimeBlock(block, operand_src); |
| 8462 | try sema.requireRuntimeBlock(block, operand_src, null); |
| 8190 | 8463 | return block.addStructFieldPtr(operand_ptr, first_field_index, field_ty_ptr); |
| 8191 | 8464 | } |
| 8192 | 8465 | |
| ... | ... | @@ -8196,7 +8469,7 @@ fn zirSwitchCapture( |
| 8196 | 8469 | operand_val.castTag(.@"union").?.data.val, |
| 8197 | 8470 | ); |
| 8198 | 8471 | } |
| 8199 | | try sema.requireRuntimeBlock(block, operand_src); |
| 8472 | try sema.requireRuntimeBlock(block, operand_src, null); |
| 8200 | 8473 | return block.addStructFieldVal(operand, first_field_index, first_field.ty); |
| 8201 | 8474 | }, |
| 8202 | 8475 | .ErrorSet => { |
| ... | ... | @@ -8206,7 +8479,7 @@ fn zirSwitchCapture( |
| 8206 | 8479 | for (items) |item| { |
| 8207 | 8480 | const item_ref = try sema.resolveInst(item); |
| 8208 | 8481 | // Previous switch validation ensured this will succeed |
| 8209 | | const item_val = sema.resolveConstValue(block, .unneeded, item_ref) catch unreachable; |
| 8482 | const item_val = sema.resolveConstValue(block, .unneeded, item_ref, undefined) catch unreachable; |
| 8210 | 8483 | names.putAssumeCapacityNoClobber( |
| 8211 | 8484 | item_val.getError().?, |
| 8212 | 8485 | {}, |
| ... | ... | @@ -8220,7 +8493,7 @@ fn zirSwitchCapture( |
| 8220 | 8493 | } else { |
| 8221 | 8494 | const item_ref = try sema.resolveInst(items[0]); |
| 8222 | 8495 | // Previous switch validation ensured this will succeed |
| 8223 | | const item_val = sema.resolveConstValue(block, .unneeded, item_ref) catch unreachable; |
| 8496 | const item_val = sema.resolveConstValue(block, .unneeded, item_ref, undefined) catch unreachable; |
| 8224 | 8497 | |
| 8225 | 8498 | const item_ty = try Type.Tag.error_set_single.create(sema.arena, item_val.getError().?); |
| 8226 | 8499 | return sema.bitCast(block, item_ty, operand, operand_src); |
| ... | ... | @@ -8247,7 +8520,7 @@ fn zirSwitchCond( |
| 8247 | 8520 | ) CompileError!Air.Inst.Ref { |
| 8248 | 8521 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 8249 | 8522 | const src = inst_data.src(); |
| 8250 | | const operand_src = src; // TODO make this point at the switch operand |
| 8523 | const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = inst_data.src_node }; |
| 8251 | 8524 | const operand_ptr = try sema.resolveInst(inst_data.operand); |
| 8252 | 8525 | const operand = if (is_ref) |
| 8253 | 8526 | try sema.analyzeLoad(block, src, operand_ptr, operand_src) |
| ... | ... | @@ -8345,12 +8618,19 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8345 | 8618 | }, |
| 8346 | 8619 | }; |
| 8347 | 8620 | |
| 8621 | const union_originally = blk: { |
| 8622 | const zir_data = sema.code.instructions.items(.data); |
| 8623 | const cond_index = Zir.refToIndex(extra.data.operand).?; |
| 8624 | const raw_operand = sema.resolveInst(zir_data[cond_index].un_node.operand) catch unreachable; |
| 8625 | break :blk sema.typeOf(raw_operand).zigTypeTag() == .Union; |
| 8626 | }; |
| 8627 | |
| 8348 | 8628 | const operand_ty = sema.typeOf(operand); |
| 8349 | 8629 | |
| 8350 | 8630 | var else_error_ty: ?Type = null; |
| 8351 | 8631 | |
| 8352 | 8632 | // Validate usage of '_' prongs. |
| 8353 | | if (special_prong == .under and !operand_ty.isNonexhaustiveEnum()) { |
| 8633 | if (special_prong == .under and (!operand_ty.isNonexhaustiveEnum() or union_originally)) { |
| 8354 | 8634 | const msg = msg: { |
| 8355 | 8635 | const msg = try sema.errMsg( |
| 8356 | 8636 | block, |
| ... | ... | @@ -8375,6 +8655,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8375 | 8655 | |
| 8376 | 8656 | // Validate for duplicate items, missing else prong, and invalid range. |
| 8377 | 8657 | switch (operand_ty.zigTypeTag()) { |
| 8658 | .Union => unreachable, // handled in zirSwitchCond |
| 8378 | 8659 | .Enum => { |
| 8379 | 8660 | var seen_fields = try gpa.alloc(?Module.SwitchProngSrc, operand_ty.enumFieldCount()); |
| 8380 | 8661 | defer gpa.free(seen_fields); |
| ... | ... | @@ -8432,60 +8713,53 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8432 | 8713 | } |
| 8433 | 8714 | const all_tags_handled = for (seen_fields) |seen_src| { |
| 8434 | 8715 | if (seen_src == null) break false; |
| 8435 | | } else !operand_ty.isNonexhaustiveEnum(); |
| 8716 | } else true; |
| 8436 | 8717 | |
| 8437 | | switch (special_prong) { |
| 8438 | | .none => { |
| 8439 | | if (!all_tags_handled) { |
| 8440 | | const msg = msg: { |
| 8441 | | const msg = try sema.errMsg( |
| 8442 | | block, |
| 8443 | | src, |
| 8444 | | "switch must handle all possibilities", |
| 8445 | | .{}, |
| 8446 | | ); |
| 8447 | | errdefer msg.destroy(sema.gpa); |
| 8448 | | for (seen_fields) |seen_src, i| { |
| 8449 | | if (seen_src != null) continue; |
| 8450 | | |
| 8451 | | const field_name = operand_ty.enumFieldName(i); |
| 8452 | | |
| 8453 | | // TODO have this point to the tag decl instead of here |
| 8454 | | try sema.errNote( |
| 8455 | | block, |
| 8456 | | src, |
| 8457 | | msg, |
| 8458 | | "unhandled enumeration value: '{s}'", |
| 8459 | | .{field_name}, |
| 8460 | | ); |
| 8461 | | } |
| 8462 | | try sema.mod.errNoteNonLazy( |
| 8463 | | operand_ty.declSrcLoc(sema.mod), |
| 8464 | | msg, |
| 8465 | | "enum '{}' declared here", |
| 8466 | | .{operand_ty.fmt(sema.mod)}, |
| 8467 | | ); |
| 8468 | | break :msg msg; |
| 8469 | | }; |
| 8470 | | return sema.failWithOwnedErrorMsg(block, msg); |
| 8471 | | } |
| 8472 | | }, |
| 8473 | | .under => { |
| 8474 | | if (all_tags_handled) return sema.fail( |
| 8718 | if (special_prong == .@"else") { |
| 8719 | if (all_tags_handled and !operand_ty.isNonexhaustiveEnum()) return sema.fail( |
| 8720 | block, |
| 8721 | special_prong_src, |
| 8722 | "unreachable else prong; all cases already handled", |
| 8723 | .{}, |
| 8724 | ); |
| 8725 | } else if (!all_tags_handled) { |
| 8726 | const msg = msg: { |
| 8727 | const msg = try sema.errMsg( |
| 8475 | 8728 | block, |
| 8476 | | special_prong_src, |
| 8477 | | "unreachable '_' prong; all cases already handled", |
| 8729 | src, |
| 8730 | "switch must handle all possibilities", |
| 8478 | 8731 | .{}, |
| 8479 | 8732 | ); |
| 8480 | | }, |
| 8481 | | .@"else" => { |
| 8482 | | if (all_tags_handled) return sema.fail( |
| 8483 | | block, |
| 8484 | | special_prong_src, |
| 8485 | | "unreachable else prong; all cases already handled", |
| 8486 | | .{}, |
| 8733 | errdefer msg.destroy(sema.gpa); |
| 8734 | for (seen_fields) |seen_src, i| { |
| 8735 | if (seen_src != null) continue; |
| 8736 | |
| 8737 | const field_name = operand_ty.enumFieldName(i); |
| 8738 | try sema.addFieldErrNote( |
| 8739 | block, |
| 8740 | operand_ty, |
| 8741 | i, |
| 8742 | msg, |
| 8743 | "unhandled enumeration value: '{s}'", |
| 8744 | .{field_name}, |
| 8745 | ); |
| 8746 | } |
| 8747 | try sema.mod.errNoteNonLazy( |
| 8748 | operand_ty.declSrcLoc(sema.mod), |
| 8749 | msg, |
| 8750 | "enum '{}' declared here", |
| 8751 | .{operand_ty.fmt(sema.mod)}, |
| 8487 | 8752 | ); |
| 8488 | | }, |
| 8753 | break :msg msg; |
| 8754 | }; |
| 8755 | return sema.failWithOwnedErrorMsg(block, msg); |
| 8756 | } else if (special_prong == .none and operand_ty.isNonexhaustiveEnum() and !union_originally) { |
| 8757 | return sema.fail( |
| 8758 | block, |
| 8759 | src, |
| 8760 | "switch on non-exhaustive enum must include 'else' or '_' prong", |
| 8761 | .{}, |
| 8762 | ); |
| 8489 | 8763 | } |
| 8490 | 8764 | }, |
| 8491 | 8765 | .ErrorSet => { |
| ... | ... | @@ -8625,7 +8899,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8625 | 8899 | else_error_ty = try Type.Tag.error_set_merged.create(sema.arena, names); |
| 8626 | 8900 | } |
| 8627 | 8901 | }, |
| 8628 | | .Union => return sema.fail(block, src, "TODO validate switch .Union", .{}), |
| 8629 | 8902 | .Int, .ComptimeInt => { |
| 8630 | 8903 | var range_set = RangeSet.init(gpa, sema.mod); |
| 8631 | 8904 | defer range_set.deinit(); |
| ... | ... | @@ -8923,7 +9196,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8923 | 9196 | |
| 8924 | 9197 | const item = try sema.resolveInst(item_ref); |
| 8925 | 9198 | // Validation above ensured these will succeed. |
| 8926 | | const item_val = sema.resolveConstValue(&child_block, .unneeded, item) catch unreachable; |
| 9199 | const item_val = sema.resolveConstValue(&child_block, .unneeded, item, undefined) catch unreachable; |
| 8927 | 9200 | if (operand_val.eql(item_val, operand_ty, sema.mod)) { |
| 8928 | 9201 | return sema.resolveBlockBody(block, src, &child_block, body, inst, merges); |
| 8929 | 9202 | } |
| ... | ... | @@ -8945,7 +9218,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8945 | 9218 | for (items) |item_ref| { |
| 8946 | 9219 | const item = try sema.resolveInst(item_ref); |
| 8947 | 9220 | // Validation above ensured these will succeed. |
| 8948 | | const item_val = sema.resolveConstValue(&child_block, .unneeded, item) catch unreachable; |
| 9221 | const item_val = sema.resolveConstValue(&child_block, .unneeded, item, undefined) catch unreachable; |
| 8949 | 9222 | if (operand_val.eql(item_val, operand_ty, sema.mod)) { |
| 8950 | 9223 | return sema.resolveBlockBody(block, src, &child_block, body, inst, merges); |
| 8951 | 9224 | } |
| ... | ... | @@ -8959,8 +9232,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8959 | 9232 | extra_index += 1; |
| 8960 | 9233 | |
| 8961 | 9234 | // Validation above ensured these will succeed. |
| 8962 | | const first_tv = sema.resolveInstConst(&child_block, .unneeded, item_first) catch unreachable; |
| 8963 | | const last_tv = sema.resolveInstConst(&child_block, .unneeded, item_last) catch unreachable; |
| 9235 | const first_tv = sema.resolveInstConst(&child_block, .unneeded, item_first, undefined) catch unreachable; |
| 9236 | const last_tv = sema.resolveInstConst(&child_block, .unneeded, item_last, undefined) catch unreachable; |
| 8964 | 9237 | if ((try sema.compare(block, src, operand_val, .gte, first_tv.val, operand_ty)) and |
| 8965 | 9238 | (try sema.compare(block, src, operand_val, .lte, last_tv.val, operand_ty))) |
| 8966 | 9239 | { |
| ... | ... | @@ -8981,7 +9254,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8981 | 9254 | return sema.resolveBlockBody(block, src, &child_block, special.body, inst, merges); |
| 8982 | 9255 | } |
| 8983 | 9256 | |
| 8984 | | try sema.requireRuntimeBlock(block, src); |
| 9257 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 8985 | 9258 | |
| 8986 | 9259 | const estimated_cases_extra = (scalar_cases_len + multi_cases_len) * |
| 8987 | 9260 | @typeInfo(Air.SwitchBr.Case).Struct.fields.len + 2; |
| ... | ... | @@ -9270,14 +9543,14 @@ fn resolveSwitchItemVal( |
| 9270 | 9543 | // Constructing a LazySrcLoc is costly because we only have the switch AST node. |
| 9271 | 9544 | // Only if we know for sure we need to report a compile error do we resolve the |
| 9272 | 9545 | // full source locations. |
| 9273 | | if (sema.resolveConstValue(block, .unneeded, item)) |val| { |
| 9546 | if (sema.resolveConstValue(block, .unneeded, item, undefined)) |val| { |
| 9274 | 9547 | return TypedValue{ .ty = item_ty, .val = val }; |
| 9275 | 9548 | } else |err| switch (err) { |
| 9276 | 9549 | error.NeededSourceLocation => { |
| 9277 | 9550 | const src = switch_prong_src.resolve(sema.gpa, sema.mod.declPtr(block.src_decl), switch_node_offset, range_expand); |
| 9278 | 9551 | return TypedValue{ |
| 9279 | 9552 | .ty = item_ty, |
| 9280 | | .val = try sema.resolveConstValue(block, src, item), |
| 9553 | .val = try sema.resolveConstValue(block, src, item, "switch prong values must be comptime known"), |
| 9281 | 9554 | }; |
| 9282 | 9555 | }, |
| 9283 | 9556 | else => |e| return e, |
| ... | ... | @@ -9463,7 +9736,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 9463 | 9736 | const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 9464 | 9737 | const name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; |
| 9465 | 9738 | const unresolved_ty = try sema.resolveType(block, ty_src, extra.lhs); |
| 9466 | | const field_name = try sema.resolveConstString(block, name_src, extra.rhs); |
| 9739 | const field_name = try sema.resolveConstString(block, name_src, extra.rhs, "field name must be comptime known"); |
| 9467 | 9740 | const ty = try sema.resolveTypeFields(block, ty_src, unresolved_ty); |
| 9468 | 9741 | |
| 9469 | 9742 | const has_field = hf: { |
| ... | ... | @@ -9505,7 +9778,7 @@ fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 9505 | 9778 | const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 9506 | 9779 | const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; |
| 9507 | 9780 | const container_type = try sema.resolveType(block, lhs_src, extra.lhs); |
| 9508 | | const decl_name = try sema.resolveConstString(block, rhs_src, extra.rhs); |
| 9781 | const decl_name = try sema.resolveConstString(block, rhs_src, extra.rhs, "decl name must be comptime known"); |
| 9509 | 9782 | |
| 9510 | 9783 | try checkNamespaceType(sema, block, lhs_src, container_type); |
| 9511 | 9784 | |
| ... | ... | @@ -9552,7 +9825,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 9552 | 9825 | const mod = sema.mod; |
| 9553 | 9826 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 9554 | 9827 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 9555 | | const name = try sema.resolveConstString(block, operand_src, inst_data.operand); |
| 9828 | const name = try sema.resolveConstString(block, operand_src, inst_data.operand, "file path name must be comptime known"); |
| 9556 | 9829 | |
| 9557 | 9830 | const embed_file = mod.embedFile(block.getFileScope(), name) catch |err| switch (err) { |
| 9558 | 9831 | error.ImportOutsidePkgPath => { |
| ... | ... | @@ -9706,13 +9979,13 @@ fn zirShl( |
| 9706 | 9979 | try lhs_ty.maxInt(sema.arena, target), |
| 9707 | 9980 | ); |
| 9708 | 9981 | const rhs_limited = try sema.analyzeMinMax(block, rhs_src, rhs, max_int, .min, rhs_src, rhs_src); |
| 9709 | | break :rhs try sema.intCast(block, lhs_ty, rhs_src, rhs_limited, rhs_src, false); |
| 9982 | break :rhs try sema.intCast(block, src, lhs_ty, rhs_src, rhs_limited, rhs_src, false); |
| 9710 | 9983 | } else { |
| 9711 | 9984 | break :rhs rhs; |
| 9712 | 9985 | } |
| 9713 | 9986 | } else rhs; |
| 9714 | 9987 | |
| 9715 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 9988 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 9716 | 9989 | if (block.wantSafety()) { |
| 9717 | 9990 | const maybe_op_ov: ?Air.Inst.Tag = switch (air_tag) { |
| 9718 | 9991 | .shl_exact => .shl_with_overflow, |
| ... | ... | @@ -9823,7 +10096,7 @@ fn zirShr( |
| 9823 | 10096 | } |
| 9824 | 10097 | } else rhs_src; |
| 9825 | 10098 | |
| 9826 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 10099 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 9827 | 10100 | return block.addBinOp(air_tag, lhs, rhs); |
| 9828 | 10101 | } |
| 9829 | 10102 | |
| ... | ... | @@ -9882,7 +10155,7 @@ fn zirBitwise( |
| 9882 | 10155 | } |
| 9883 | 10156 | }; |
| 9884 | 10157 | |
| 9885 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 10158 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 9886 | 10159 | return block.addBinOp(air_tag, casted_lhs, casted_rhs); |
| 9887 | 10160 | } |
| 9888 | 10161 | |
| ... | ... | @@ -9926,7 +10199,7 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 9926 | 10199 | } |
| 9927 | 10200 | } |
| 9928 | 10201 | |
| 9929 | | try sema.requireRuntimeBlock(block, src); |
| 10202 | try sema.requireRuntimeBlock(block, src, null); |
| 9930 | 10203 | return block.addTyOp(.not, operand_type, operand); |
| 9931 | 10204 | } |
| 9932 | 10205 | |
| ... | ... | @@ -9939,6 +10212,7 @@ fn analyzeTupleCat( |
| 9939 | 10212 | ) CompileError!Air.Inst.Ref { |
| 9940 | 10213 | const lhs_ty = sema.typeOf(lhs); |
| 9941 | 10214 | const rhs_ty = sema.typeOf(rhs); |
| 10215 | const src = LazySrcLoc.nodeOffset(src_node); |
| 9942 | 10216 | const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = src_node }; |
| 9943 | 10217 | const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = src_node }; |
| 9944 | 10218 | |
| ... | ... | @@ -9986,7 +10260,7 @@ fn analyzeTupleCat( |
| 9986 | 10260 | return sema.addConstant(tuple_ty, tuple_val); |
| 9987 | 10261 | }; |
| 9988 | 10262 | |
| 9989 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 10263 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 9990 | 10264 | |
| 9991 | 10265 | const element_refs = try sema.arena.alloc(Air.Inst.Ref, final_len); |
| 9992 | 10266 | for (lhs_tuple.types) |_, i| { |
| ... | ... | @@ -10049,8 +10323,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 10049 | 10323 | const rhs_sent = try sema.addConstant(rhs_info.elem_type, rhs_sent_val); |
| 10050 | 10324 | const lhs_sent_casted = try sema.coerce(block, resolved_elem_ty, lhs_sent, lhs_src); |
| 10051 | 10325 | const rhs_sent_casted = try sema.coerce(block, resolved_elem_ty, rhs_sent, rhs_src); |
| 10052 | | const lhs_sent_casted_val = try sema.resolveConstValue(block, lhs_src, lhs_sent_casted); |
| 10053 | | const rhs_sent_casted_val = try sema.resolveConstValue(block, rhs_src, rhs_sent_casted); |
| 10326 | const lhs_sent_casted_val = try sema.resolveConstValue(block, lhs_src, lhs_sent_casted, "array sentinel value must be comptime known"); |
| 10327 | const rhs_sent_casted_val = try sema.resolveConstValue(block, rhs_src, rhs_sent_casted, "array sentinel value must be comptime known"); |
| 10054 | 10328 | if (try sema.valuesEqual(block, src, lhs_sent_casted_val, rhs_sent_casted_val, resolved_elem_ty)) { |
| 10055 | 10329 | break :s lhs_sent_casted_val; |
| 10056 | 10330 | } else { |
| ... | ... | @@ -10058,14 +10332,14 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 10058 | 10332 | } |
| 10059 | 10333 | } else { |
| 10060 | 10334 | const lhs_sent_casted = try sema.coerce(block, resolved_elem_ty, lhs_sent, lhs_src); |
| 10061 | | const lhs_sent_casted_val = try sema.resolveConstValue(block, lhs_src, lhs_sent_casted); |
| 10335 | const lhs_sent_casted_val = try sema.resolveConstValue(block, lhs_src, lhs_sent_casted, "array sentinel value must be comptime known"); |
| 10062 | 10336 | break :s lhs_sent_casted_val; |
| 10063 | 10337 | } |
| 10064 | 10338 | } else { |
| 10065 | 10339 | if (rhs_info.sentinel) |rhs_sent_val| { |
| 10066 | 10340 | const rhs_sent = try sema.addConstant(rhs_info.elem_type, rhs_sent_val); |
| 10067 | 10341 | const rhs_sent_casted = try sema.coerce(block, resolved_elem_ty, rhs_sent, rhs_src); |
| 10068 | | const rhs_sent_casted_val = try sema.resolveConstValue(block, rhs_src, rhs_sent_casted); |
| 10342 | const rhs_sent_casted_val = try sema.resolveConstValue(block, rhs_src, rhs_sent_casted, "array sentinel value must be comptime known"); |
| 10069 | 10343 | break :s rhs_sent_casted_val; |
| 10070 | 10344 | } else { |
| 10071 | 10345 | break :s null; |
| ... | ... | @@ -10120,7 +10394,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 10120 | 10394 | } else break :rs rhs_src; |
| 10121 | 10395 | } else lhs_src; |
| 10122 | 10396 | |
| 10123 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 10397 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 10124 | 10398 | |
| 10125 | 10399 | if (ptr_addrspace) |ptr_as| { |
| 10126 | 10400 | const alloc_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| ... | ... | @@ -10186,7 +10460,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins |
| 10186 | 10460 | // has a sentinel, and this code should compute the length based |
| 10187 | 10461 | // on the sentinel value. |
| 10188 | 10462 | .Slice, .Many => { |
| 10189 | | const val = try sema.resolveConstValue(block, src, operand); |
| 10463 | const val = try sema.resolveConstValue(block, src, operand, "slice value being concatenated must be comptime known"); |
| 10190 | 10464 | return Type.ArrayInfo{ |
| 10191 | 10465 | .elem_type = ptr_info.pointee_type, |
| 10192 | 10466 | .sentinel = ptr_info.sentinel, |
| ... | ... | @@ -10215,6 +10489,7 @@ fn analyzeTupleMul( |
| 10215 | 10489 | ) CompileError!Air.Inst.Ref { |
| 10216 | 10490 | const operand_ty = sema.typeOf(operand); |
| 10217 | 10491 | const operand_tuple = operand_ty.tupleFields(); |
| 10492 | const src = LazySrcLoc.nodeOffset(src_node); |
| 10218 | 10493 | const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = src_node }; |
| 10219 | 10494 | const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = src_node }; |
| 10220 | 10495 | |
| ... | ... | @@ -10258,7 +10533,7 @@ fn analyzeTupleMul( |
| 10258 | 10533 | return sema.addConstant(tuple_ty, tuple_val); |
| 10259 | 10534 | }; |
| 10260 | 10535 | |
| 10261 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 10536 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 10262 | 10537 | |
| 10263 | 10538 | const element_refs = try sema.arena.alloc(Air.Inst.Ref, final_len); |
| 10264 | 10539 | for (operand_tuple.types) |_, i| { |
| ... | ... | @@ -10286,7 +10561,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 10286 | 10561 | const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; |
| 10287 | 10562 | |
| 10288 | 10563 | // In `**` rhs must be comptime-known, but lhs can be runtime-known |
| 10289 | | const factor = try sema.resolveInt(block, rhs_src, extra.rhs, Type.usize); |
| 10564 | const factor = try sema.resolveInt(block, rhs_src, extra.rhs, Type.usize, "array multiplication factor must be comptime known"); |
| 10290 | 10565 | |
| 10291 | 10566 | if (lhs_ty.isTuple()) { |
| 10292 | 10567 | return sema.analyzeTupleMul(block, inst_data.src_node, lhs, factor); |
| ... | ... | @@ -10337,7 +10612,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 10337 | 10612 | return sema.addConstantMaybeRef(block, src, result_ty, val, ptr_addrspace != null); |
| 10338 | 10613 | } |
| 10339 | 10614 | |
| 10340 | | try sema.requireRuntimeBlock(block, lhs_src); |
| 10615 | try sema.requireRuntimeBlock(block, src, lhs_src); |
| 10341 | 10616 | |
| 10342 | 10617 | if (ptr_addrspace) |ptr_as| { |
| 10343 | 10618 | const alloc_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| ... | ... | @@ -10411,7 +10686,7 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 10411 | 10686 | const target = sema.mod.getTarget(); |
| 10412 | 10687 | return sema.addConstant(rhs_ty, try rhs_val.floatNeg(rhs_ty, sema.arena, target)); |
| 10413 | 10688 | } |
| 10414 | | try sema.requireRuntimeBlock(block, rhs_src); |
| 10689 | try sema.requireRuntimeBlock(block, src, null); |
| 10415 | 10690 | return block.addUnOp(.neg, rhs); |
| 10416 | 10691 | } |
| 10417 | 10692 | |
| ... | ... | @@ -10495,7 +10770,7 @@ fn zirOverflowArithmetic( |
| 10495 | 10770 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 10496 | 10771 | const dest_ty = lhs_ty; |
| 10497 | 10772 | if (dest_ty.scalarType().zigTypeTag() != .Int) { |
| 10498 | | return sema.fail(block, src, "expected vector of integers or integer type, found '{}'", .{dest_ty.fmt(mod)}); |
| 10773 | return sema.fail(block, src, "expected vector of integers or integer tag type, found '{}'", .{dest_ty.fmt(mod)}); |
| 10499 | 10774 | } |
| 10500 | 10775 | |
| 10501 | 10776 | const maybe_lhs_val = try sema.resolveMaybeUndefVal(block, lhs_src, lhs); |
| ... | ... | @@ -10635,7 +10910,8 @@ fn zirOverflowArithmetic( |
| 10635 | 10910 | else => unreachable, |
| 10636 | 10911 | }; |
| 10637 | 10912 | |
| 10638 | | try sema.requireRuntimeBlock(block, src); |
| 10913 | const runtime_src = if (maybe_lhs_val == null) lhs_src else rhs_src; |
| 10914 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 10639 | 10915 | |
| 10640 | 10916 | const tuple = try block.addInst(.{ |
| 10641 | 10917 | .tag = air_tag, |
| ... | ... | @@ -11542,7 +11818,7 @@ fn analyzeArithmetic( |
| 11542 | 11818 | } |
| 11543 | 11819 | }; |
| 11544 | 11820 | |
| 11545 | | try sema.requireRuntimeBlock(block, rs.src); |
| 11821 | try sema.requireRuntimeBlock(block, src, rs.src); |
| 11546 | 11822 | if (block.wantSafety()) { |
| 11547 | 11823 | if (scalar_tag == .Int) { |
| 11548 | 11824 | const maybe_op_ov: ?Air.Inst.Tag = switch (rs.air_tag) { |
| ... | ... | @@ -11666,7 +11942,7 @@ fn analyzePtrArithmetic( |
| 11666 | 11942 | } else break :rs ptr_src; |
| 11667 | 11943 | }; |
| 11668 | 11944 | |
| 11669 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 11945 | try sema.requireRuntimeBlock(block, op_src, runtime_src); |
| 11670 | 11946 | return block.addInst(.{ |
| 11671 | 11947 | .tag = air_tag, |
| 11672 | 11948 | .data = .{ .ty_pl = .{ |
| ... | ... | @@ -11685,7 +11961,7 @@ fn zirLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.In |
| 11685 | 11961 | |
| 11686 | 11962 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 11687 | 11963 | const src = inst_data.src(); |
| 11688 | | const ptr_src: LazySrcLoc = .{ .node_offset_deref_ptr = inst_data.src_node }; |
| 11964 | const ptr_src = src; // TODO better source location |
| 11689 | 11965 | const ptr = try sema.resolveInst(inst_data.operand); |
| 11690 | 11966 | return sema.analyzeLoad(block, src, ptr, ptr_src); |
| 11691 | 11967 | } |
| ... | ... | @@ -11733,7 +12009,7 @@ fn zirAsm( |
| 11733 | 12009 | } |
| 11734 | 12010 | |
| 11735 | 12011 | if (block.is_comptime) { |
| 11736 | | try sema.requireRuntimeBlock(block, src); |
| 12012 | try sema.requireRuntimeBlock(block, src, null); |
| 11737 | 12013 | } |
| 11738 | 12014 | |
| 11739 | 12015 | var extra_i = extra.end; |
| ... | ... | @@ -11895,10 +12171,10 @@ fn zirCmpEq( |
| 11895 | 12171 | } |
| 11896 | 12172 | |
| 11897 | 12173 | if (lhs_ty_tag == .Union and (rhs_ty_tag == .EnumLiteral or rhs_ty_tag == .Enum)) { |
| 11898 | | return sema.analyzeCmpUnionTag(block, lhs, lhs_src, rhs, rhs_src, op); |
| 12174 | return sema.analyzeCmpUnionTag(block, src, lhs, lhs_src, rhs, rhs_src, op); |
| 11899 | 12175 | } |
| 11900 | 12176 | if (rhs_ty_tag == .Union and (lhs_ty_tag == .EnumLiteral or lhs_ty_tag == .Enum)) { |
| 11901 | | return sema.analyzeCmpUnionTag(block, rhs, rhs_src, lhs, lhs_src, op); |
| 12177 | return sema.analyzeCmpUnionTag(block, src, rhs, rhs_src, lhs, lhs_src, op); |
| 11902 | 12178 | } |
| 11903 | 12179 | |
| 11904 | 12180 | if (lhs_ty_tag == .ErrorSet and rhs_ty_tag == .ErrorSet) { |
| ... | ... | @@ -11925,7 +12201,7 @@ fn zirCmpEq( |
| 11925 | 12201 | break :src lhs_src; |
| 11926 | 12202 | } |
| 11927 | 12203 | }; |
| 11928 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 12204 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 11929 | 12205 | return block.addBinOp(air_tag, lhs, rhs); |
| 11930 | 12206 | } |
| 11931 | 12207 | if (lhs_ty_tag == .Type and rhs_ty_tag == .Type) { |
| ... | ... | @@ -11943,6 +12219,7 @@ fn zirCmpEq( |
| 11943 | 12219 | fn analyzeCmpUnionTag( |
| 11944 | 12220 | sema: *Sema, |
| 11945 | 12221 | block: *Block, |
| 12222 | src: LazySrcLoc, |
| 11946 | 12223 | un: Air.Inst.Ref, |
| 11947 | 12224 | un_src: LazySrcLoc, |
| 11948 | 12225 | tag: Air.Inst.Ref, |
| ... | ... | @@ -11964,7 +12241,7 @@ fn analyzeCmpUnionTag( |
| 11964 | 12241 | const coerced_tag = try sema.coerce(block, union_tag_ty, tag, tag_src); |
| 11965 | 12242 | const coerced_union = try sema.coerce(block, union_tag_ty, un, un_src); |
| 11966 | 12243 | |
| 11967 | | return sema.cmpSelf(block, coerced_union, coerced_tag, op, un_src, tag_src); |
| 12244 | return sema.cmpSelf(block, src, coerced_union, coerced_tag, op, un_src, tag_src); |
| 11968 | 12245 | } |
| 11969 | 12246 | |
| 11970 | 12247 | /// Only called for non-equality operators. See also `zirCmpEq`. |
| ... | ... | @@ -12020,7 +12297,7 @@ fn analyzeCmp( |
| 12020 | 12297 | } |
| 12021 | 12298 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 12022 | 12299 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| 12023 | | return sema.cmpSelf(block, casted_lhs, casted_rhs, op, lhs_src, rhs_src); |
| 12300 | return sema.cmpSelf(block, src, casted_lhs, casted_rhs, op, lhs_src, rhs_src); |
| 12024 | 12301 | } |
| 12025 | 12302 | |
| 12026 | 12303 | fn compareOperatorName(comp: std.math.CompareOperator) []const u8 { |
| ... | ... | @@ -12037,6 +12314,7 @@ fn compareOperatorName(comp: std.math.CompareOperator) []const u8 { |
| 12037 | 12314 | fn cmpSelf( |
| 12038 | 12315 | sema: *Sema, |
| 12039 | 12316 | block: *Block, |
| 12317 | src: LazySrcLoc, |
| 12040 | 12318 | casted_lhs: Air.Inst.Ref, |
| 12041 | 12319 | casted_rhs: Air.Inst.Ref, |
| 12042 | 12320 | op: std.math.CompareOperator, |
| ... | ... | @@ -12064,7 +12342,7 @@ fn cmpSelf( |
| 12064 | 12342 | } else { |
| 12065 | 12343 | if (resolved_type.zigTypeTag() == .Bool) { |
| 12066 | 12344 | // We can lower bool eq/neq more efficiently. |
| 12067 | | return sema.runtimeBoolCmp(block, op, casted_rhs, lhs_val.toBool(), rhs_src); |
| 12345 | return sema.runtimeBoolCmp(block, src, op, casted_rhs, lhs_val.toBool(), rhs_src); |
| 12068 | 12346 | } |
| 12069 | 12347 | break :src rhs_src; |
| 12070 | 12348 | } |
| ... | ... | @@ -12074,13 +12352,13 @@ fn cmpSelf( |
| 12074 | 12352 | if (resolved_type.zigTypeTag() == .Bool) { |
| 12075 | 12353 | if (try sema.resolveMaybeUndefVal(block, rhs_src, casted_rhs)) |rhs_val| { |
| 12076 | 12354 | if (rhs_val.isUndef()) return sema.addConstUndef(Type.bool); |
| 12077 | | return sema.runtimeBoolCmp(block, op, casted_lhs, rhs_val.toBool(), lhs_src); |
| 12355 | return sema.runtimeBoolCmp(block, src, op, casted_lhs, rhs_val.toBool(), lhs_src); |
| 12078 | 12356 | } |
| 12079 | 12357 | } |
| 12080 | 12358 | break :src lhs_src; |
| 12081 | 12359 | } |
| 12082 | 12360 | }; |
| 12083 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 12361 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 12084 | 12362 | if (resolved_type.zigTypeTag() == .Vector) { |
| 12085 | 12363 | const result_ty = try Type.vector(sema.arena, resolved_type.vectorLen(), Type.@"bool"); |
| 12086 | 12364 | const result_ty_ref = try sema.addType(result_ty); |
| ... | ... | @@ -12097,13 +12375,14 @@ fn cmpSelf( |
| 12097 | 12375 | fn runtimeBoolCmp( |
| 12098 | 12376 | sema: *Sema, |
| 12099 | 12377 | block: *Block, |
| 12378 | src: LazySrcLoc, |
| 12100 | 12379 | op: std.math.CompareOperator, |
| 12101 | 12380 | lhs: Air.Inst.Ref, |
| 12102 | 12381 | rhs: bool, |
| 12103 | 12382 | runtime_src: LazySrcLoc, |
| 12104 | 12383 | ) CompileError!Air.Inst.Ref { |
| 12105 | 12384 | if ((op == .neq) == rhs) { |
| 12106 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 12385 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 12107 | 12386 | return block.addTyOp(.not, Type.bool, lhs); |
| 12108 | 12387 | } else { |
| 12109 | 12388 | return lhs; |
| ... | ... | @@ -12225,7 +12504,7 @@ fn zirRetAddr( |
| 12225 | 12504 | extended: Zir.Inst.Extended.InstData, |
| 12226 | 12505 | ) CompileError!Air.Inst.Ref { |
| 12227 | 12506 | const src = LazySrcLoc.nodeOffset(@bitCast(i32, extended.operand)); |
| 12228 | | try sema.requireRuntimeBlock(block, src); |
| 12507 | try sema.requireRuntimeBlock(block, src, null); |
| 12229 | 12508 | return try block.addNoOp(.ret_addr); |
| 12230 | 12509 | } |
| 12231 | 12510 | |
| ... | ... | @@ -12235,7 +12514,7 @@ fn zirFrameAddress( |
| 12235 | 12514 | extended: Zir.Inst.Extended.InstData, |
| 12236 | 12515 | ) CompileError!Air.Inst.Ref { |
| 12237 | 12516 | const src = LazySrcLoc.nodeOffset(@bitCast(i32, extended.operand)); |
| 12238 | | try sema.requireRuntimeBlock(block, src); |
| 12517 | try sema.requireRuntimeBlock(block, src, null); |
| 12239 | 12518 | return try block.addNoOp(.frame_addr); |
| 12240 | 12519 | } |
| 12241 | 12520 | |
| ... | ... | @@ -13304,7 +13583,7 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 13304 | 13583 | else |
| 13305 | 13584 | Air.Inst.Ref.bool_true; |
| 13306 | 13585 | } |
| 13307 | | try sema.requireRuntimeBlock(block, src); |
| 13586 | try sema.requireRuntimeBlock(block, src, null); |
| 13308 | 13587 | return block.addTyOp(.not, Type.bool, operand); |
| 13309 | 13588 | } |
| 13310 | 13589 | |
| ... | ... | @@ -13689,7 +13968,7 @@ fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 13689 | 13968 | if (block.is_comptime or inst_data.force_comptime) { |
| 13690 | 13969 | return sema.fail(block, src, "reached unreachable code", .{}); |
| 13691 | 13970 | } |
| 13692 | | try sema.requireRuntimeBlock(block, src); |
| 13971 | try sema.requireFunctionBlock(block, src); |
| 13693 | 13972 | // TODO Add compile error for @optimizeFor occurring too late in a scope. |
| 13694 | 13973 | try block.addUnreachable(src, true); |
| 13695 | 13974 | return always_noreturn; |
| ... | ... | @@ -13751,7 +14030,6 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir |
| 13751 | 14030 | const operand = try sema.analyzeLoad(block, src, ret_ptr, src); |
| 13752 | 14031 | return sema.analyzeRet(block, operand, src); |
| 13753 | 14032 | } |
| 13754 | | try sema.requireRuntimeBlock(block, src); |
| 13755 | 14033 | _ = try block.addUnOp(.ret_load, ret_ptr); |
| 13756 | 14034 | return always_noreturn; |
| 13757 | 14035 | } |
| ... | ... | @@ -13834,22 +14112,21 @@ fn floatOpAllowed(tag: Zir.Inst.Tag) bool { |
| 13834 | 14112 | }; |
| 13835 | 14113 | } |
| 13836 | 14114 | |
| 13837 | | fn zirPtrTypeSimple(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 14115 | fn zirOverflowArithmeticPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 13838 | 14116 | const tracy = trace(@src()); |
| 13839 | 14117 | defer tracy.end(); |
| 13840 | 14118 | |
| 13841 | | const inst_data = sema.code.instructions.items(.data)[inst].ptr_type_simple; |
| 13842 | | const elem_ty_src = sema.src; // TODO better source location |
| 13843 | | const elem_type = try sema.resolveType(block, elem_ty_src, inst_data.elem_type); |
| 14119 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 14120 | const elem_ty_src = inst_data.src(); |
| 14121 | const elem_type = try sema.resolveType(block, elem_ty_src, inst_data.operand); |
| 13844 | 14122 | const ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 13845 | 14123 | .pointee_type = elem_type, |
| 13846 | 14124 | .@"addrspace" = .generic, |
| 13847 | | .mutable = inst_data.is_mutable, |
| 13848 | | .@"allowzero" = inst_data.is_allowzero or inst_data.size == .C, |
| 13849 | | .@"volatile" = inst_data.is_volatile, |
| 13850 | | .size = inst_data.size, |
| 14125 | .mutable = true, |
| 14126 | .@"allowzero" = false, |
| 14127 | .@"volatile" = false, |
| 14128 | .size = .One, |
| 13851 | 14129 | }); |
| 13852 | | try sema.validatePtrTy(block, elem_ty_src, ty); |
| 13853 | 14130 | return sema.addType(ty); |
| 13854 | 14131 | } |
| 13855 | 14132 | |
| ... | ... | @@ -13857,14 +14134,15 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 13857 | 14134 | const tracy = trace(@src()); |
| 13858 | 14135 | defer tracy.end(); |
| 13859 | 14136 | |
| 13860 | | const src: LazySrcLoc = sema.src; // TODO better source location |
| 13861 | | const elem_ty_src: LazySrcLoc = sema.src; // TODO better source location |
| 13862 | | const sentinel_src: LazySrcLoc = sema.src; // TODO better source location |
| 13863 | | const addrspace_src: LazySrcLoc = sema.src; // TODO better source location |
| 13864 | | const bitoffset_src: LazySrcLoc = sema.src; // TODO better source location |
| 13865 | | const hostsize_src: LazySrcLoc = sema.src; // TODO better source location |
| 13866 | 14137 | const inst_data = sema.code.instructions.items(.data)[inst].ptr_type; |
| 13867 | 14138 | const extra = sema.code.extraData(Zir.Inst.PtrType, inst_data.payload_index); |
| 14139 | const elem_ty_src: LazySrcLoc = .{ .node_offset_ptr_elem = extra.data.src_node }; |
| 14140 | const sentinel_src: LazySrcLoc = .{ .node_offset_ptr_sentinel = extra.data.src_node }; |
| 14141 | const align_src: LazySrcLoc = .{ .node_offset_ptr_align = extra.data.src_node }; |
| 14142 | const addrspace_src: LazySrcLoc = .{ .node_offset_ptr_addrspace = extra.data.src_node }; |
| 14143 | const bitoffset_src: LazySrcLoc = .{ .node_offset_ptr_bitoffset = extra.data.src_node }; |
| 14144 | const hostsize_src: LazySrcLoc = .{ .node_offset_ptr_hostsize = extra.data.src_node }; |
| 14145 | |
| 13868 | 14146 | const unresolved_elem_ty = try sema.resolveType(block, elem_ty_src, extra.data.elem_type); |
| 13869 | 14147 | const target = sema.mod.getTarget(); |
| 13870 | 14148 | |
| ... | ... | @@ -13873,14 +14151,14 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 13873 | 14151 | const sentinel = if (inst_data.flags.has_sentinel) blk: { |
| 13874 | 14152 | const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]); |
| 13875 | 14153 | extra_i += 1; |
| 13876 | | break :blk (try sema.resolveInstConst(block, sentinel_src, ref)).val; |
| 14154 | break :blk (try sema.resolveInstConst(block, sentinel_src, ref, "pointer sentinel value must be comptime known")).val; |
| 13877 | 14155 | } else null; |
| 13878 | 14156 | |
| 13879 | 14157 | const abi_align: u32 = if (inst_data.flags.has_align) blk: { |
| 13880 | 14158 | const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]); |
| 13881 | 14159 | extra_i += 1; |
| 13882 | | const coerced = try sema.coerce(block, Type.u32, try sema.resolveInst(ref), src); |
| 13883 | | const val = try sema.resolveConstValue(block, src, coerced); |
| 14160 | const coerced = try sema.coerce(block, Type.u32, try sema.resolveInst(ref), align_src); |
| 14161 | const val = try sema.resolveConstValue(block, align_src, coerced, "pointer alignment must be comptime known"); |
| 13884 | 14162 | // Check if this happens to be the lazy alignment of our element type, in |
| 13885 | 14163 | // which case we can make this 0 without resolving it. |
| 13886 | 14164 | if (val.castTag(.lazy_align)) |payload| { |
| ... | ... | @@ -13888,8 +14166,9 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 13888 | 14166 | break :blk 0; |
| 13889 | 14167 | } |
| 13890 | 14168 | } |
| 13891 | | const abi_align = (try val.getUnsignedIntAdvanced(target, sema.kit(block, src))).?; |
| 13892 | | break :blk @intCast(u32, abi_align); |
| 14169 | const abi_align = @intCast(u32, (try val.getUnsignedIntAdvanced(target, sema.kit(block, align_src))).?); |
| 14170 | try sema.validateAlign(block, align_src, abi_align); |
| 14171 | break :blk abi_align; |
| 13893 | 14172 | } else 0; |
| 13894 | 14173 | |
| 13895 | 14174 | const address_space = if (inst_data.flags.has_addrspace) blk: { |
| ... | ... | @@ -13901,19 +14180,19 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 13901 | 14180 | const bit_offset = if (inst_data.flags.has_bit_range) blk: { |
| 13902 | 14181 | const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]); |
| 13903 | 14182 | extra_i += 1; |
| 13904 | | const bit_offset = try sema.resolveInt(block, bitoffset_src, ref, Type.u16); |
| 14183 | const bit_offset = try sema.resolveInt(block, bitoffset_src, ref, Type.u16, "pointer bit-offset must be comptime known"); |
| 13905 | 14184 | break :blk @intCast(u16, bit_offset); |
| 13906 | 14185 | } else 0; |
| 13907 | 14186 | |
| 13908 | 14187 | const host_size: u16 = if (inst_data.flags.has_bit_range) blk: { |
| 13909 | 14188 | const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]); |
| 13910 | 14189 | extra_i += 1; |
| 13911 | | const host_size = try sema.resolveInt(block, hostsize_src, ref, Type.u16); |
| 14190 | const host_size = try sema.resolveInt(block, hostsize_src, ref, Type.u16, "pointer host size must be comptime known"); |
| 13912 | 14191 | break :blk @intCast(u16, host_size); |
| 13913 | 14192 | } else 0; |
| 13914 | 14193 | |
| 13915 | 14194 | if (host_size != 0 and bit_offset >= host_size * 8) { |
| 13916 | | return sema.fail(block, src, "bit offset starts after end of host integer", .{}); |
| 14195 | return sema.fail(block, bitoffset_src, "bit offset starts after end of host integer", .{}); |
| 13917 | 14196 | } |
| 13918 | 14197 | |
| 13919 | 14198 | const elem_ty = if (abi_align == 0) |
| ... | ... | @@ -13923,48 +14202,53 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 13923 | 14202 | try sema.resolveTypeLayout(block, elem_ty_src, elem_ty); |
| 13924 | 14203 | break :t elem_ty; |
| 13925 | 14204 | }; |
| 13926 | | const ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 13927 | | .pointee_type = elem_ty, |
| 13928 | | .sentinel = sentinel, |
| 13929 | | .@"align" = abi_align, |
| 13930 | | .@"addrspace" = address_space, |
| 13931 | | .bit_offset = bit_offset, |
| 13932 | | .host_size = host_size, |
| 13933 | | .mutable = inst_data.flags.is_mutable, |
| 13934 | | .@"allowzero" = inst_data.flags.is_allowzero, |
| 13935 | | .@"volatile" = inst_data.flags.is_volatile, |
| 13936 | | .size = inst_data.size, |
| 13937 | | }); |
| 13938 | | try sema.validatePtrTy(block, elem_ty_src, ty); |
| 13939 | | return sema.addType(ty); |
| 13940 | | } |
| 13941 | 14205 | |
| 13942 | | fn validatePtrTy(sema: *Sema, block: *Block, elem_src: LazySrcLoc, ty: Type) CompileError!void { |
| 13943 | | const ptr_info = ty.ptrInfo().data; |
| 13944 | | const pointee_tag = ptr_info.pointee_type.zigTypeTag(); |
| 13945 | | if (pointee_tag == .NoReturn) { |
| 13946 | | return sema.fail(block, elem_src, "pointer to noreturn not allowed", .{}); |
| 13947 | | } else if (ptr_info.size == .Many and pointee_tag == .Opaque) { |
| 13948 | | return sema.fail(block, elem_src, "unknown-length pointer to opaque not allowed", .{}); |
| 13949 | | } else if (ptr_info.size == .C) { |
| 13950 | | const elem_ty = ptr_info.pointee_type; |
| 14206 | if (elem_ty.zigTypeTag() == .NoReturn) { |
| 14207 | return sema.fail(block, elem_ty_src, "pointer to noreturn not allowed", .{}); |
| 14208 | } else if (elem_ty.zigTypeTag() == .Fn) { |
| 14209 | if (inst_data.size != .One) { |
| 14210 | return sema.fail(block, elem_ty_src, "function pointers must be single pointers", .{}); |
| 14211 | } |
| 14212 | const fn_align = elem_ty.fnInfo().alignment; |
| 14213 | if (inst_data.flags.has_align and abi_align != 0 and fn_align != 0 and |
| 14214 | abi_align != fn_align) |
| 14215 | { |
| 14216 | return sema.fail(block, align_src, "function pointer alignment disagrees with function alignment", .{}); |
| 14217 | } |
| 14218 | } else if (inst_data.size == .Many and elem_ty.zigTypeTag() == .Opaque) { |
| 14219 | return sema.fail(block, elem_ty_src, "unknown-length pointer to opaque not allowed", .{}); |
| 14220 | } else if (inst_data.size == .C) { |
| 13951 | 14221 | if (!(try sema.validateExternType(elem_ty, .other))) { |
| 13952 | 14222 | const msg = msg: { |
| 13953 | | const msg = try sema.errMsg(block, elem_src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(sema.mod)}); |
| 14223 | const msg = try sema.errMsg(block, elem_ty_src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(sema.mod)}); |
| 13954 | 14224 | errdefer msg.destroy(sema.gpa); |
| 13955 | 14225 | |
| 13956 | 14226 | const src_decl = sema.mod.declPtr(block.src_decl); |
| 13957 | | try sema.explainWhyTypeIsNotExtern(block, elem_src, msg, elem_src.toSrcLoc(src_decl), elem_ty, .other); |
| 14227 | try sema.explainWhyTypeIsNotExtern(block, elem_ty_src, msg, elem_ty_src.toSrcLoc(src_decl), elem_ty, .other); |
| 13958 | 14228 | |
| 13959 | 14229 | try sema.addDeclaredHereNote(msg, elem_ty); |
| 13960 | 14230 | break :msg msg; |
| 13961 | 14231 | }; |
| 13962 | 14232 | return sema.failWithOwnedErrorMsg(block, msg); |
| 13963 | 14233 | } |
| 13964 | | if (pointee_tag == .Opaque) { |
| 13965 | | return sema.fail(block, elem_src, "C pointers cannot point to opaque types", .{}); |
| 14234 | if (elem_ty.zigTypeTag() == .Opaque) { |
| 14235 | return sema.fail(block, elem_ty_src, "C pointers cannot point to opaque types", .{}); |
| 13966 | 14236 | } |
| 13967 | 14237 | } |
| 14238 | |
| 14239 | const ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 14240 | .pointee_type = elem_ty, |
| 14241 | .sentinel = sentinel, |
| 14242 | .@"align" = abi_align, |
| 14243 | .@"addrspace" = address_space, |
| 14244 | .bit_offset = bit_offset, |
| 14245 | .host_size = host_size, |
| 14246 | .mutable = inst_data.flags.is_mutable, |
| 14247 | .@"allowzero" = inst_data.flags.is_allowzero, |
| 14248 | .@"volatile" = inst_data.flags.is_volatile, |
| 14249 | .size = inst_data.size, |
| 14250 | }); |
| 14251 | return sema.addType(ty); |
| 13968 | 14252 | } |
| 13969 | 14253 | |
| 13970 | 14254 | fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | ... | @@ -14018,7 +14302,7 @@ fn zirUnionInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 14018 | 14302 | const init_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node }; |
| 14019 | 14303 | const extra = sema.code.extraData(Zir.Inst.UnionInit, inst_data.payload_index).data; |
| 14020 | 14304 | const union_ty = try sema.resolveType(block, ty_src, extra.union_type); |
| 14021 | | const field_name = try sema.resolveConstString(block, field_src, extra.field_name); |
| 14305 | const field_name = try sema.resolveConstString(block, field_src, extra.field_name, "name of field being initialized must be comptime known"); |
| 14022 | 14306 | const init = try sema.resolveInst(extra.init); |
| 14023 | 14307 | return sema.unionInit(block, init, init_src, union_ty, ty_src, field_name, field_src); |
| 14024 | 14308 | } |
| ... | ... | @@ -14045,7 +14329,7 @@ fn unionInit( |
| 14045 | 14329 | })); |
| 14046 | 14330 | } |
| 14047 | 14331 | |
| 14048 | | try sema.requireRuntimeBlock(block, init_src); |
| 14332 | try sema.requireRuntimeBlock(block, init_src, null); |
| 14049 | 14333 | _ = union_ty_src; |
| 14050 | 14334 | try sema.queueFullTypeResolution(union_ty); |
| 14051 | 14335 | return block.addUnionInit(union_ty, field_index, init); |
| ... | ... | @@ -14150,7 +14434,7 @@ fn zirStructInit( |
| 14150 | 14434 | return alloc; |
| 14151 | 14435 | } |
| 14152 | 14436 | |
| 14153 | | try sema.requireRuntimeBlock(block, src); |
| 14437 | try sema.requireRuntimeBlock(block, src, null); |
| 14154 | 14438 | try sema.queueFullTypeResolution(resolved_ty); |
| 14155 | 14439 | return block.addUnionInit(resolved_ty, field_index, init_inst); |
| 14156 | 14440 | } else if (resolved_ty.isAnonStruct()) { |
| ... | ... | @@ -14255,7 +14539,7 @@ fn finishStructInit( |
| 14255 | 14539 | return alloc; |
| 14256 | 14540 | } |
| 14257 | 14541 | |
| 14258 | | try sema.requireRuntimeBlock(block, dest_src); |
| 14542 | try sema.requireRuntimeBlock(block, dest_src, null); |
| 14259 | 14543 | try sema.queueFullTypeResolution(struct_ty); |
| 14260 | 14544 | return block.addAggregateInit(struct_ty, field_inits); |
| 14261 | 14545 | } |
| ... | ... | @@ -14277,13 +14561,23 @@ fn zirStructInitAnon( |
| 14277 | 14561 | var runtime_src: ?LazySrcLoc = null; |
| 14278 | 14562 | var extra_index = extra.end; |
| 14279 | 14563 | for (types) |*field_ty, i| { |
| 14564 | const init_src = src; // TODO better source location |
| 14280 | 14565 | const item = sema.code.extraData(Zir.Inst.StructInitAnon.Item, extra_index); |
| 14281 | 14566 | extra_index = item.end; |
| 14282 | 14567 | |
| 14283 | 14568 | names[i] = sema.code.nullTerminatedString(item.data.field_name); |
| 14284 | 14569 | const init = try sema.resolveInst(item.data.init); |
| 14285 | 14570 | field_ty.* = sema.typeOf(init); |
| 14286 | | const init_src = src; // TODO better source location |
| 14571 | if (types[i].zigTypeTag() == .Opaque) { |
| 14572 | const msg = msg: { |
| 14573 | const msg = try sema.errMsg(block, init_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{}); |
| 14574 | errdefer msg.destroy(sema.gpa); |
| 14575 | |
| 14576 | try sema.addDeclaredHereNote(msg, types[i]); |
| 14577 | break :msg msg; |
| 14578 | }; |
| 14579 | return sema.failWithOwnedErrorMsg(block, msg); |
| 14580 | } |
| 14287 | 14581 | if (try sema.resolveMaybeUndefVal(block, init_src, init)) |init_val| { |
| 14288 | 14582 | values[i] = init_val; |
| 14289 | 14583 | } else { |
| ... | ... | @@ -14305,7 +14599,7 @@ fn zirStructInitAnon( |
| 14305 | 14599 | return sema.addConstantMaybeRef(block, src, tuple_ty, tuple_val, is_ref); |
| 14306 | 14600 | }; |
| 14307 | 14601 | |
| 14308 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 14602 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 14309 | 14603 | |
| 14310 | 14604 | if (is_ref) { |
| 14311 | 14605 | const target = sema.mod.getTarget(); |
| ... | ... | @@ -14397,7 +14691,7 @@ fn zirArrayInit( |
| 14397 | 14691 | return sema.addConstantMaybeRef(block, src, array_ty, array_val, is_ref); |
| 14398 | 14692 | }; |
| 14399 | 14693 | |
| 14400 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 14694 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 14401 | 14695 | try sema.queueFullTypeResolution(array_ty); |
| 14402 | 14696 | |
| 14403 | 14697 | if (is_ref) { |
| ... | ... | @@ -14460,9 +14754,19 @@ fn zirArrayInitAnon( |
| 14460 | 14754 | const opt_runtime_src = rs: { |
| 14461 | 14755 | var runtime_src: ?LazySrcLoc = null; |
| 14462 | 14756 | for (operands) |operand, i| { |
| 14757 | const operand_src = src; // TODO better source location |
| 14463 | 14758 | const elem = try sema.resolveInst(operand); |
| 14464 | 14759 | types[i] = sema.typeOf(elem); |
| 14465 | | const operand_src = src; // TODO better source location |
| 14760 | if (types[i].zigTypeTag() == .Opaque) { |
| 14761 | const msg = msg: { |
| 14762 | const msg = try sema.errMsg(block, operand_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{}); |
| 14763 | errdefer msg.destroy(sema.gpa); |
| 14764 | |
| 14765 | try sema.addDeclaredHereNote(msg, types[i]); |
| 14766 | break :msg msg; |
| 14767 | }; |
| 14768 | return sema.failWithOwnedErrorMsg(block, msg); |
| 14769 | } |
| 14466 | 14770 | if (try sema.resolveMaybeUndefVal(block, operand_src, elem)) |val| { |
| 14467 | 14771 | values[i] = val; |
| 14468 | 14772 | } else { |
| ... | ... | @@ -14483,7 +14787,7 @@ fn zirArrayInitAnon( |
| 14483 | 14787 | return sema.addConstantMaybeRef(block, src, tuple_ty, tuple_val, is_ref); |
| 14484 | 14788 | }; |
| 14485 | 14789 | |
| 14486 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 14790 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 14487 | 14791 | |
| 14488 | 14792 | if (is_ref) { |
| 14489 | 14793 | const target = sema.mod.getTarget(); |
| ... | ... | @@ -14542,7 +14846,7 @@ fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 14542 | 14846 | const ty_src = inst_data.src(); |
| 14543 | 14847 | const field_src = inst_data.src(); |
| 14544 | 14848 | const aggregate_ty = try sema.resolveType(block, ty_src, extra.container_type); |
| 14545 | | const field_name = try sema.resolveConstString(block, field_src, extra.field_name); |
| 14849 | const field_name = try sema.resolveConstString(block, field_src, extra.field_name, "field name must be comptime known"); |
| 14546 | 14850 | return sema.fieldType(block, aggregate_ty, field_name, field_src, ty_src); |
| 14547 | 14851 | } |
| 14548 | 14852 | |
| ... | ... | @@ -14732,7 +15036,7 @@ fn zirUnaryMath( |
| 14732 | 15036 | ); |
| 14733 | 15037 | } |
| 14734 | 15038 | |
| 14735 | | try sema.requireRuntimeBlock(block, operand_src); |
| 15039 | try sema.requireRuntimeBlock(block, operand_src, null); |
| 14736 | 15040 | return block.addUnOp(air_tag, operand); |
| 14737 | 15041 | }, |
| 14738 | 15042 | .ComptimeFloat, .Float => { |
| ... | ... | @@ -14743,7 +15047,7 @@ fn zirUnaryMath( |
| 14743 | 15047 | return sema.addConstant(operand_ty, result_val); |
| 14744 | 15048 | } |
| 14745 | 15049 | |
| 14746 | | try sema.requireRuntimeBlock(block, operand_src); |
| 15050 | try sema.requireRuntimeBlock(block, operand_src, null); |
| 14747 | 15051 | return block.addUnOp(air_tag, operand); |
| 14748 | 15052 | }, |
| 14749 | 15053 | else => unreachable, |
| ... | ... | @@ -14761,7 +15065,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 14761 | 15065 | try sema.resolveTypeLayout(block, operand_src, operand_ty); |
| 14762 | 15066 | const enum_ty = switch (operand_ty.zigTypeTag()) { |
| 14763 | 15067 | .EnumLiteral => { |
| 14764 | | const val = try sema.resolveConstValue(block, operand_src, operand); |
| 15068 | const val = try sema.resolveConstValue(block, .unneeded, operand, undefined); |
| 14765 | 15069 | const bytes = val.castTag(.enum_literal).?.data; |
| 14766 | 15070 | return sema.addStrLit(block, bytes); |
| 14767 | 15071 | }, |
| ... | ... | @@ -14813,7 +15117,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I |
| 14813 | 15117 | const uncasted_operand = try sema.resolveInst(inst_data.operand); |
| 14814 | 15118 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 14815 | 15119 | const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src); |
| 14816 | | const val = try sema.resolveConstValue(block, operand_src, type_info); |
| 15120 | const val = try sema.resolveConstValue(block, operand_src, type_info, "operand to @Type must be comptime known"); |
| 14817 | 15121 | const union_val = val.cast(Value.Payload.Union).?.data; |
| 14818 | 15122 | const tag_ty = type_info_ty.unionTagType().?; |
| 14819 | 15123 | const target = mod.getTarget(); |
| ... | ... | @@ -15497,10 +15801,10 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 15497 | 15801 | const result_val = try sema.floatToInt(block, operand_src, val, operand_ty, dest_ty); |
| 15498 | 15802 | return sema.addConstant(dest_ty, result_val); |
| 15499 | 15803 | } else if (dest_ty.zigTypeTag() == .ComptimeInt) { |
| 15500 | | return sema.failWithNeededComptime(block, operand_src); |
| 15804 | return sema.failWithNeededComptime(block, operand_src, "value being casted to 'comptime_int' must be comptime known"); |
| 15501 | 15805 | } |
| 15502 | 15806 | |
| 15503 | | try sema.requireRuntimeBlock(block, operand_src); |
| 15807 | try sema.requireRuntimeBlock(block, inst_data.src(), operand_src); |
| 15504 | 15808 | return block.addTyOp(.float_to_int, dest_ty, operand); |
| 15505 | 15809 | } |
| 15506 | 15810 | |
| ... | ... | @@ -15521,10 +15825,10 @@ fn zirIntToFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 15521 | 15825 | const result_val = try val.intToFloat(sema.arena, operand_ty, dest_ty, target); |
| 15522 | 15826 | return sema.addConstant(dest_ty, result_val); |
| 15523 | 15827 | } else if (dest_ty.zigTypeTag() == .ComptimeFloat) { |
| 15524 | | return sema.failWithNeededComptime(block, operand_src); |
| 15828 | return sema.failWithNeededComptime(block, operand_src, "value being casted to 'comptime_float' must be comptime known"); |
| 15525 | 15829 | } |
| 15526 | 15830 | |
| 15527 | | try sema.requireRuntimeBlock(block, operand_src); |
| 15831 | try sema.requireRuntimeBlock(block, inst_data.src(), operand_src); |
| 15528 | 15832 | return block.addTyOp(.int_to_float, dest_ty, operand); |
| 15529 | 15833 | } |
| 15530 | 15834 | |
| ... | ... | @@ -15560,7 +15864,7 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15560 | 15864 | return sema.addConstant(type_res, Value.initPayload(&val_payload.base)); |
| 15561 | 15865 | } |
| 15562 | 15866 | |
| 15563 | | try sema.requireRuntimeBlock(block, src); |
| 15867 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 15564 | 15868 | if (block.wantSafety()) { |
| 15565 | 15869 | if (!type_res.isAllowzeroPtr()) { |
| 15566 | 15870 | const is_non_zero = try block.addBinOp(.cmp_neq, operand_coerced, .zero_usize); |
| ... | ... | @@ -15657,7 +15961,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat |
| 15657 | 15961 | return sema.addConstant(dest_ty, val); |
| 15658 | 15962 | } |
| 15659 | 15963 | |
| 15660 | | try sema.requireRuntimeBlock(block, src); |
| 15964 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 15661 | 15965 | if (block.wantSafety() and !dest_ty.isAnyError()) { |
| 15662 | 15966 | const err_int_inst = try block.addBitCast(Type.u16, operand); |
| 15663 | 15967 | // TODO: Output a switch instead of chained OR's. |
| ... | ... | @@ -15812,7 +16116,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15812 | 16116 | ); |
| 15813 | 16117 | } |
| 15814 | 16118 | |
| 15815 | | try sema.requireRuntimeBlock(block, src); |
| 16119 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 15816 | 16120 | return block.addTyOp(.trunc, dest_ty, operand); |
| 15817 | 16121 | } |
| 15818 | 16122 | |
| ... | ... | @@ -15855,6 +16159,7 @@ fn zirBitCount( |
| 15855 | 16159 | comptimeOp: fn (val: Value, ty: Type, target: std.Target) u64, |
| 15856 | 16160 | ) CompileError!Air.Inst.Ref { |
| 15857 | 16161 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 16162 | const src = inst_data.src(); |
| 15858 | 16163 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; |
| 15859 | 16164 | const operand = try sema.resolveInst(inst_data.operand); |
| 15860 | 16165 | const operand_ty = sema.typeOf(operand); |
| ... | ... | @@ -15887,7 +16192,7 @@ fn zirBitCount( |
| 15887 | 16192 | try Value.Tag.aggregate.create(sema.arena, elems), |
| 15888 | 16193 | ); |
| 15889 | 16194 | } else { |
| 15890 | | try sema.requireRuntimeBlock(block, operand_src); |
| 16195 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 15891 | 16196 | return block.addTyOp(air_tag, result_ty, operand); |
| 15892 | 16197 | } |
| 15893 | 16198 | }, |
| ... | ... | @@ -15896,7 +16201,7 @@ fn zirBitCount( |
| 15896 | 16201 | if (val.isUndef()) return sema.addConstUndef(result_scalar_ty); |
| 15897 | 16202 | return sema.addIntUnsigned(result_scalar_ty, comptimeOp(val, operand_ty, target)); |
| 15898 | 16203 | } else { |
| 15899 | | try sema.requireRuntimeBlock(block, operand_src); |
| 16204 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 15900 | 16205 | return block.addTyOp(air_tag, result_scalar_ty, operand); |
| 15901 | 16206 | } |
| 15902 | 16207 | }, |
| ... | ... | @@ -15906,6 +16211,7 @@ fn zirBitCount( |
| 15906 | 16211 | |
| 15907 | 16212 | fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 15908 | 16213 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 16214 | const src = inst_data.src(); |
| 15909 | 16215 | const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 15910 | 16216 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; |
| 15911 | 16217 | const operand = try sema.resolveInst(inst_data.operand); |
| ... | ... | @@ -15934,7 +16240,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15934 | 16240 | return sema.addConstant(operand_ty, result_val); |
| 15935 | 16241 | } else operand_src; |
| 15936 | 16242 | |
| 15937 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 16243 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 15938 | 16244 | return block.addTyOp(.byte_swap, operand_ty, operand); |
| 15939 | 16245 | }, |
| 15940 | 16246 | .Vector => { |
| ... | ... | @@ -15955,7 +16261,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15955 | 16261 | ); |
| 15956 | 16262 | } else operand_src; |
| 15957 | 16263 | |
| 15958 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 16264 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 15959 | 16265 | return block.addTyOp(.byte_swap, operand_ty, operand); |
| 15960 | 16266 | }, |
| 15961 | 16267 | else => unreachable, |
| ... | ... | @@ -15964,6 +16270,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15964 | 16270 | |
| 15965 | 16271 | fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 15966 | 16272 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 16273 | const src = inst_data.src(); |
| 15967 | 16274 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; |
| 15968 | 16275 | const operand = try sema.resolveInst(inst_data.operand); |
| 15969 | 16276 | const operand_ty = sema.typeOf(operand); |
| ... | ... | @@ -15982,7 +16289,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 15982 | 16289 | return sema.addConstant(operand_ty, result_val); |
| 15983 | 16290 | } else operand_src; |
| 15984 | 16291 | |
| 15985 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 16292 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 15986 | 16293 | return block.addTyOp(.bit_reverse, operand_ty, operand); |
| 15987 | 16294 | }, |
| 15988 | 16295 | .Vector => { |
| ... | ... | @@ -16003,7 +16310,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 16003 | 16310 | ); |
| 16004 | 16311 | } else operand_src; |
| 16005 | 16312 | |
| 16006 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 16313 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 16007 | 16314 | return block.addTyOp(.bit_reverse, operand_ty, operand); |
| 16008 | 16315 | }, |
| 16009 | 16316 | else => unreachable, |
| ... | ... | @@ -16030,7 +16337,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6 |
| 16030 | 16337 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 16031 | 16338 | |
| 16032 | 16339 | const ty = try sema.resolveType(block, lhs_src, extra.lhs); |
| 16033 | | const field_name = try sema.resolveConstString(block, rhs_src, extra.rhs); |
| 16340 | const field_name = try sema.resolveConstString(block, rhs_src, extra.rhs, "name of field must be comptime known"); |
| 16034 | 16341 | const target = sema.mod.getTarget(); |
| 16035 | 16342 | |
| 16036 | 16343 | try sema.resolveTypeLayout(block, lhs_src, ty); |
| ... | ... | @@ -16451,19 +16758,19 @@ fn resolveExportOptions( |
| 16451 | 16758 | const options = try sema.coerce(block, export_options_ty, air_ref, src); |
| 16452 | 16759 | |
| 16453 | 16760 | const name_operand = try sema.fieldVal(block, src, options, "name", src); |
| 16454 | | const name_val = try sema.resolveConstValue(block, src, name_operand); |
| 16761 | const name_val = try sema.resolveConstValue(block, src, name_operand, "name of exported value must be comptime known"); |
| 16455 | 16762 | const name_ty = Type.initTag(.const_slice_u8); |
| 16456 | 16763 | const name = try name_val.toAllocatedBytes(name_ty, sema.arena, sema.mod); |
| 16457 | 16764 | |
| 16458 | 16765 | const linkage_operand = try sema.fieldVal(block, src, options, "linkage", src); |
| 16459 | | const linkage_val = try sema.resolveConstValue(block, src, linkage_operand); |
| 16766 | const linkage_val = try sema.resolveConstValue(block, src, linkage_operand, "linkage of exported value must be comptime known"); |
| 16460 | 16767 | const linkage = linkage_val.toEnum(std.builtin.GlobalLinkage); |
| 16461 | 16768 | |
| 16462 | 16769 | const section = try sema.fieldVal(block, src, options, "section", src); |
| 16463 | | const section_val = try sema.resolveConstValue(block, src, section); |
| 16770 | const section_val = try sema.resolveConstValue(block, src, section, "linksection of exported value must be comptime known"); |
| 16464 | 16771 | |
| 16465 | 16772 | const visibility_operand = try sema.fieldVal(block, src, options, "visibility", src); |
| 16466 | | const visibility_val = try sema.resolveConstValue(block, src, visibility_operand); |
| 16773 | const visibility_val = try sema.resolveConstValue(block, src, visibility_operand, "visibility of exported value must be comptime known"); |
| 16467 | 16774 | const visibility = visibility_val.toEnum(std.builtin.SymbolVisibility); |
| 16468 | 16775 | |
| 16469 | 16776 | if (name.len < 1) { |
| ... | ... | @@ -16494,11 +16801,12 @@ fn resolveBuiltinEnum( |
| 16494 | 16801 | src: LazySrcLoc, |
| 16495 | 16802 | zir_ref: Zir.Inst.Ref, |
| 16496 | 16803 | comptime name: []const u8, |
| 16804 | reason: []const u8, |
| 16497 | 16805 | ) CompileError!@field(std.builtin, name) { |
| 16498 | 16806 | const ty = try sema.getBuiltinType(block, src, name); |
| 16499 | 16807 | const air_ref = try sema.resolveInst(zir_ref); |
| 16500 | 16808 | const coerced = try sema.coerce(block, ty, air_ref, src); |
| 16501 | | const val = try sema.resolveConstValue(block, src, coerced); |
| 16809 | const val = try sema.resolveConstValue(block, src, coerced, reason); |
| 16502 | 16810 | return val.toEnum(@field(std.builtin, name)); |
| 16503 | 16811 | } |
| 16504 | 16812 | |
| ... | ... | @@ -16507,8 +16815,9 @@ fn resolveAtomicOrder( |
| 16507 | 16815 | block: *Block, |
| 16508 | 16816 | src: LazySrcLoc, |
| 16509 | 16817 | zir_ref: Zir.Inst.Ref, |
| 16818 | reason: []const u8, |
| 16510 | 16819 | ) CompileError!std.builtin.AtomicOrder { |
| 16511 | | return resolveBuiltinEnum(sema, block, src, zir_ref, "AtomicOrder"); |
| 16820 | return resolveBuiltinEnum(sema, block, src, zir_ref, "AtomicOrder", reason); |
| 16512 | 16821 | } |
| 16513 | 16822 | |
| 16514 | 16823 | fn resolveAtomicRmwOp( |
| ... | ... | @@ -16517,7 +16826,7 @@ fn resolveAtomicRmwOp( |
| 16517 | 16826 | src: LazySrcLoc, |
| 16518 | 16827 | zir_ref: Zir.Inst.Ref, |
| 16519 | 16828 | ) CompileError!std.builtin.AtomicRmwOp { |
| 16520 | | return resolveBuiltinEnum(sema, block, src, zir_ref, "AtomicRmwOp"); |
| 16829 | return resolveBuiltinEnum(sema, block, src, zir_ref, "AtomicRmwOp", "@atomicRmW operation must be comptime known"); |
| 16521 | 16830 | } |
| 16522 | 16831 | |
| 16523 | 16832 | fn zirCmpxchg( |
| ... | ... | @@ -16550,8 +16859,8 @@ fn zirCmpxchg( |
| 16550 | 16859 | const uncasted_ptr = try sema.resolveInst(extra.ptr); |
| 16551 | 16860 | const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, false); |
| 16552 | 16861 | const new_value = try sema.coerce(block, elem_ty, try sema.resolveInst(extra.new_value), new_value_src); |
| 16553 | | const success_order = try sema.resolveAtomicOrder(block, success_order_src, extra.success_order); |
| 16554 | | const failure_order = try sema.resolveAtomicOrder(block, failure_order_src, extra.failure_order); |
| 16862 | const success_order = try sema.resolveAtomicOrder(block, success_order_src, extra.success_order, "atomic order of cmpxchg success must be comptime known"); |
| 16863 | const failure_order = try sema.resolveAtomicOrder(block, failure_order_src, extra.failure_order, "atomic order of cmpxchg failure must be comptime known"); |
| 16555 | 16864 | |
| 16556 | 16865 | if (@enumToInt(success_order) < @enumToInt(std.builtin.AtomicOrder.Monotonic)) { |
| 16557 | 16866 | return sema.fail(block, success_order_src, "success atomic ordering must be Monotonic or stricter", .{}); |
| ... | ... | @@ -16596,7 +16905,7 @@ fn zirCmpxchg( |
| 16596 | 16905 | const flags: u32 = @as(u32, @enumToInt(success_order)) | |
| 16597 | 16906 | (@as(u32, @enumToInt(failure_order)) << 3); |
| 16598 | 16907 | |
| 16599 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 16908 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 16600 | 16909 | return block.addInst(.{ |
| 16601 | 16910 | .tag = air_tag, |
| 16602 | 16911 | .data = .{ .ty_pl = .{ |
| ... | ... | @@ -16616,7 +16925,7 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I |
| 16616 | 16925 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 16617 | 16926 | const len_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; |
| 16618 | 16927 | const scalar_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; |
| 16619 | | const len = @intCast(u32, try sema.resolveInt(block, len_src, extra.lhs, Type.u32)); |
| 16928 | const len = @intCast(u32, try sema.resolveInt(block, len_src, extra.lhs, Type.u32, "vector splat destination length must be comptime known")); |
| 16620 | 16929 | const scalar = try sema.resolveInst(extra.rhs); |
| 16621 | 16930 | const scalar_ty = sema.typeOf(scalar); |
| 16622 | 16931 | try sema.checkVectorElemType(block, scalar_src, scalar_ty); |
| ... | ... | @@ -16633,7 +16942,7 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I |
| 16633 | 16942 | ); |
| 16634 | 16943 | } |
| 16635 | 16944 | |
| 16636 | | try sema.requireRuntimeBlock(block, scalar_src); |
| 16945 | try sema.requireRuntimeBlock(block, inst_data.src(), scalar_src); |
| 16637 | 16946 | return block.addTyOp(.splat, vector_ty, scalar); |
| 16638 | 16947 | } |
| 16639 | 16948 | |
| ... | ... | @@ -16642,7 +16951,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 16642 | 16951 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 16643 | 16952 | const op_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 16644 | 16953 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; |
| 16645 | | const operation = try sema.resolveBuiltinEnum(block, op_src, extra.lhs, "ReduceOp"); |
| 16954 | const operation = try sema.resolveBuiltinEnum(block, op_src, extra.lhs, "ReduceOp", "@reduce operation must be comptime known"); |
| 16646 | 16955 | const operand = try sema.resolveInst(extra.rhs); |
| 16647 | 16956 | const operand_ty = sema.typeOf(operand); |
| 16648 | 16957 | const target = sema.mod.getTarget(); |
| ... | ... | @@ -16697,7 +17006,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 16697 | 17006 | return sema.addConstant(scalar_ty, accum); |
| 16698 | 17007 | } |
| 16699 | 17008 | |
| 16700 | | try sema.requireRuntimeBlock(block, operand_src); |
| 17009 | try sema.requireRuntimeBlock(block, inst_data.src(), operand_src); |
| 16701 | 17010 | return block.addInst(.{ |
| 16702 | 17011 | .tag = .reduce, |
| 16703 | 17012 | .data = .{ .reduce = .{ |
| ... | ... | @@ -16729,7 +17038,7 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 16729 | 17038 | .elem_type = Type.@"i32", |
| 16730 | 17039 | }); |
| 16731 | 17040 | mask = try sema.coerce(block, mask_ty, mask, mask_src); |
| 16732 | | const mask_val = try sema.resolveConstMaybeUndefVal(block, mask_src, mask); |
| 17041 | const mask_val = try sema.resolveConstMaybeUndefVal(block, mask_src, mask, "shuffle mask must be comptime known"); |
| 16733 | 17042 | return sema.analyzeShuffle(block, inst_data.src_node, elem_ty, a, b, mask_val, @intCast(u32, mask_len)); |
| 16734 | 17043 | } |
| 16735 | 17044 | |
| ... | ... | @@ -16901,6 +17210,7 @@ fn analyzeShuffle( |
| 16901 | 17210 | fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { |
| 16902 | 17211 | const extra = sema.code.extraData(Zir.Inst.Select, extended.operand).data; |
| 16903 | 17212 | |
| 17213 | const src = LazySrcLoc.nodeOffset(extra.node); |
| 16904 | 17214 | const elem_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node }; |
| 16905 | 17215 | const pred_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node }; |
| 16906 | 17216 | const a_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = extra.node }; |
| ... | ... | @@ -16972,7 +17282,7 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C |
| 16972 | 17282 | break :rs pred_src; |
| 16973 | 17283 | }; |
| 16974 | 17284 | |
| 16975 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 17285 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 16976 | 17286 | return block.addInst(.{ |
| 16977 | 17287 | .tag = .select, |
| 16978 | 17288 | .data = .{ .pl_op = .{ |
| ... | ... | @@ -16996,7 +17306,7 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 16996 | 17306 | const elem_ty = try sema.resolveType(block, elem_ty_src, extra.elem_type); |
| 16997 | 17307 | const uncasted_ptr = try sema.resolveInst(extra.ptr); |
| 16998 | 17308 | const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, true); |
| 16999 | | const order = try sema.resolveAtomicOrder(block, order_src, extra.ordering); |
| 17309 | const order = try sema.resolveAtomicOrder(block, order_src, extra.ordering, "atomic order of @atomicLoad must be comptime known"); |
| 17000 | 17310 | |
| 17001 | 17311 | switch (order) { |
| 17002 | 17312 | .Release, .AcqRel => { |
| ... | ... | @@ -17020,7 +17330,7 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 17020 | 17330 | } |
| 17021 | 17331 | } |
| 17022 | 17332 | |
| 17023 | | try sema.requireRuntimeBlock(block, ptr_src); |
| 17333 | try sema.requireRuntimeBlock(block, inst_data.src(), ptr_src); |
| 17024 | 17334 | return block.addInst(.{ |
| 17025 | 17335 | .tag = .atomic_load, |
| 17026 | 17336 | .data = .{ .atomic_load = .{ |
| ... | ... | @@ -17060,7 +17370,7 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 17060 | 17370 | }, |
| 17061 | 17371 | else => {}, |
| 17062 | 17372 | } |
| 17063 | | const order = try sema.resolveAtomicOrder(block, order_src, extra.ordering); |
| 17373 | const order = try sema.resolveAtomicOrder(block, order_src, extra.ordering, "atomic order of @atomicRmW must be comptime known"); |
| 17064 | 17374 | |
| 17065 | 17375 | if (order == .Unordered) { |
| 17066 | 17376 | return sema.fail(block, order_src, "@atomicRmw atomic ordering must not be Unordered", .{}); |
| ... | ... | @@ -17101,7 +17411,7 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 17101 | 17411 | |
| 17102 | 17412 | const flags: u32 = @as(u32, @enumToInt(order)) | (@as(u32, @enumToInt(op)) << 3); |
| 17103 | 17413 | |
| 17104 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 17414 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 17105 | 17415 | return block.addInst(.{ |
| 17106 | 17416 | .tag = .atomic_rmw, |
| 17107 | 17417 | .data = .{ .pl_op = .{ |
| ... | ... | @@ -17128,7 +17438,7 @@ fn zirAtomicStore(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 17128 | 17438 | const elem_ty = sema.typeOf(operand); |
| 17129 | 17439 | const uncasted_ptr = try sema.resolveInst(extra.ptr); |
| 17130 | 17440 | const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, false); |
| 17131 | | const order = try sema.resolveAtomicOrder(block, order_src, extra.ordering); |
| 17441 | const order = try sema.resolveAtomicOrder(block, order_src, extra.ordering, "atomic order of @atomicStore must be comptime known"); |
| 17132 | 17442 | |
| 17133 | 17443 | const air_tag: Air.Inst.Tag = switch (order) { |
| 17134 | 17444 | .Acquire, .AcqRel => { |
| ... | ... | @@ -17200,7 +17510,7 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 17200 | 17510 | break :rs mulend1_src; |
| 17201 | 17511 | }; |
| 17202 | 17512 | |
| 17203 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 17513 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 17204 | 17514 | return block.addInst(.{ |
| 17205 | 17515 | .tag = .mul_add, |
| 17206 | 17516 | .data = .{ .pl_op = .{ |
| ... | ... | @@ -17233,10 +17543,10 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 17233 | 17543 | const coerced_options = try sema.coerce(block, call_options_ty, options, options_src); |
| 17234 | 17544 | |
| 17235 | 17545 | const modifier = try sema.fieldVal(block, options_src, coerced_options, "modifier", options_src); |
| 17236 | | const modifier_val = try sema.resolveConstValue(block, options_src, modifier); |
| 17546 | const modifier_val = try sema.resolveConstValue(block, options_src, modifier, "call modifier must be comptime known"); |
| 17237 | 17547 | |
| 17238 | 17548 | const stack = try sema.fieldVal(block, options_src, coerced_options, "stack", options_src); |
| 17239 | | const stack_val = try sema.resolveConstValue(block, options_src, stack); |
| 17549 | const stack_val = try sema.resolveConstValue(block, options_src, stack, "call stack value must be comptime known"); |
| 17240 | 17550 | |
| 17241 | 17551 | if (!stack_val.isNull()) { |
| 17242 | 17552 | return sema.fail(block, options_src, "TODO: implement @call with stack", .{}); |
| ... | ... | @@ -17297,7 +17607,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 17297 | 17607 | |
| 17298 | 17608 | // Desugar bound functions here |
| 17299 | 17609 | if (sema.typeOf(func).tag() == .bound_fn) { |
| 17300 | | const bound_func = try sema.resolveValue(block, func_src, func); |
| 17610 | const bound_func = try sema.resolveValue(block, .unneeded, func, undefined); |
| 17301 | 17611 | const bound_data = &bound_func.cast(Value.Payload.BoundFn).?.data; |
| 17302 | 17612 | func = bound_data.func_inst; |
| 17303 | 17613 | resolved_args = try sema.arena.alloc(Air.Inst.Ref, args_ty.structFieldCount() + 1); |
| ... | ... | @@ -17324,7 +17634,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr |
| 17324 | 17634 | const ptr_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node }; |
| 17325 | 17635 | |
| 17326 | 17636 | const struct_ty = try sema.resolveType(block, ty_src, extra.parent_type); |
| 17327 | | const field_name = try sema.resolveConstString(block, name_src, extra.field_name); |
| 17637 | const field_name = try sema.resolveConstString(block, name_src, extra.field_name, "field name must be comptime known"); |
| 17328 | 17638 | const field_ptr = try sema.resolveInst(extra.field_ptr); |
| 17329 | 17639 | const field_ptr_ty = sema.typeOf(field_ptr); |
| 17330 | 17640 | |
| ... | ... | @@ -17389,7 +17699,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr |
| 17389 | 17699 | return sema.addConstant(result_ptr, payload.data.container_ptr); |
| 17390 | 17700 | } |
| 17391 | 17701 | |
| 17392 | | try sema.requireRuntimeBlock(block, src); |
| 17702 | try sema.requireRuntimeBlock(block, src, ptr_src); |
| 17393 | 17703 | return block.addInst(.{ |
| 17394 | 17704 | .tag = .field_parent_ptr, |
| 17395 | 17705 | .data = .{ .ty_pl = .{ |
| ... | ... | @@ -17470,7 +17780,7 @@ fn analyzeMinMax( |
| 17470 | 17780 | break :rs lhs_src; |
| 17471 | 17781 | }; |
| 17472 | 17782 | |
| 17473 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 17783 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 17474 | 17784 | return block.addBinOp(air_tag, simd_op.lhs, simd_op.rhs); |
| 17475 | 17785 | } |
| 17476 | 17786 | |
| ... | ... | @@ -17518,7 +17828,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 17518 | 17828 | } else break :rs src_src; |
| 17519 | 17829 | } else dest_src; |
| 17520 | 17830 | |
| 17521 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 17831 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 17522 | 17832 | _ = try block.addInst(.{ |
| 17523 | 17833 | .tag = .memcpy, |
| 17524 | 17834 | .data = .{ .pl_op = .{ |
| ... | ... | @@ -17560,7 +17870,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 17560 | 17870 | } else break :rs len_src; |
| 17561 | 17871 | } else dest_src; |
| 17562 | 17872 | |
| 17563 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 17873 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 17564 | 17874 | _ = try block.addInst(.{ |
| 17565 | 17875 | .tag = .memset, |
| 17566 | 17876 | .data = .{ .pl_op = .{ |
| ... | ... | @@ -17656,7 +17966,7 @@ fn zirVarExtended( |
| 17656 | 17966 | uncasted_init; |
| 17657 | 17967 | |
| 17658 | 17968 | break :blk (try sema.resolveMaybeUndefVal(block, init_src, init)) orelse |
| 17659 | | return sema.failWithNeededComptime(block, init_src); |
| 17969 | return sema.failWithNeededComptime(block, init_src, "container level variable initializers must be comptime known"); |
| 17660 | 17970 | } else Value.initTag(.unreachable_value); |
| 17661 | 17971 | |
| 17662 | 17972 | try sema.validateVarType(block, name_src, var_ty, small.is_extern); |
| ... | ... | @@ -17694,15 +18004,15 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 17694 | 18004 | defer tracy.end(); |
| 17695 | 18005 | |
| 17696 | 18006 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 17697 | | const src = inst_data.src(); |
| 17698 | 18007 | const extra = sema.code.extraData(Zir.Inst.FuncFancy, inst_data.payload_index); |
| 17699 | 18008 | const target = sema.mod.getTarget(); |
| 17700 | 18009 | |
| 17701 | | const align_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at align |
| 17702 | | const addrspace_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at addrspace |
| 17703 | | const section_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at section |
| 18010 | const align_src: LazySrcLoc = .{ .node_offset_fn_type_align = inst_data.src_node }; |
| 18011 | const addrspace_src: LazySrcLoc = .{ .node_offset_fn_type_addrspace = inst_data.src_node }; |
| 18012 | const section_src: LazySrcLoc = .{ .node_offset_fn_type_section = inst_data.src_node }; |
| 17704 | 18013 | const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = inst_data.src_node }; |
| 17705 | | const ret_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at the return type |
| 18014 | const ret_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = inst_data.src_node }; |
| 18015 | const has_body = extra.data.body_len != 0; |
| 17706 | 18016 | |
| 17707 | 18017 | var extra_index: usize = extra.end; |
| 17708 | 18018 | |
| ... | ... | @@ -17712,17 +18022,25 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 17712 | 18022 | break :blk lib_name; |
| 17713 | 18023 | } else null; |
| 17714 | 18024 | |
| 18025 | if (has_body and |
| 18026 | (extra.data.bits.has_align_body or extra.data.bits.has_align_ref) and |
| 18027 | !target_util.supportsFunctionAlignment(target)) |
| 18028 | { |
| 18029 | return sema.fail(block, align_src, "target does not support function alignment", .{}); |
| 18030 | } |
| 18031 | |
| 17715 | 18032 | const @"align": ?u32 = if (extra.data.bits.has_align_body) blk: { |
| 17716 | 18033 | const body_len = sema.code.extra[extra_index]; |
| 17717 | 18034 | extra_index += 1; |
| 17718 | 18035 | const body = sema.code.extra[extra_index..][0..body_len]; |
| 17719 | 18036 | extra_index += body.len; |
| 17720 | 18037 | |
| 17721 | | const val = try sema.resolveGenericBody(block, align_src, body, inst, Type.u29); |
| 18038 | const val = try sema.resolveGenericBody(block, align_src, body, inst, Type.u29, "alignment must be comptime known"); |
| 17722 | 18039 | if (val.tag() == .generic_poison) { |
| 17723 | 18040 | break :blk null; |
| 17724 | 18041 | } |
| 17725 | 18042 | const alignment = @intCast(u32, val.toUnsignedInt(target)); |
| 18043 | try sema.validateAlign(block, align_src, alignment); |
| 17726 | 18044 | if (alignment == target_util.defaultFunctionAlignment(target)) { |
| 17727 | 18045 | break :blk 0; |
| 17728 | 18046 | } else { |
| ... | ... | @@ -17731,13 +18049,14 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 17731 | 18049 | } else if (extra.data.bits.has_align_ref) blk: { |
| 17732 | 18050 | const align_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); |
| 17733 | 18051 | extra_index += 1; |
| 17734 | | const align_tv = sema.resolveInstConst(block, align_src, align_ref) catch |err| switch (err) { |
| 18052 | const align_tv = sema.resolveInstConst(block, align_src, align_ref, "alignment must be comptime known") catch |err| switch (err) { |
| 17735 | 18053 | error.GenericPoison => { |
| 17736 | 18054 | break :blk null; |
| 17737 | 18055 | }, |
| 17738 | 18056 | else => |e| return e, |
| 17739 | 18057 | }; |
| 17740 | 18058 | const alignment = @intCast(u32, align_tv.val.toUnsignedInt(target)); |
| 18059 | try sema.validateAlign(block, align_src, alignment); |
| 17741 | 18060 | if (alignment == target_util.defaultFunctionAlignment(target)) { |
| 17742 | 18061 | break :blk 0; |
| 17743 | 18062 | } else { |
| ... | ... | @@ -17752,7 +18071,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 17752 | 18071 | extra_index += body.len; |
| 17753 | 18072 | |
| 17754 | 18073 | const addrspace_ty = try sema.getBuiltinType(block, addrspace_src, "AddressSpace"); |
| 17755 | | const val = try sema.resolveGenericBody(block, addrspace_src, body, inst, addrspace_ty); |
| 18074 | const val = try sema.resolveGenericBody(block, addrspace_src, body, inst, addrspace_ty, "addrespace must be comptime known"); |
| 17756 | 18075 | if (val.tag() == .generic_poison) { |
| 17757 | 18076 | break :blk null; |
| 17758 | 18077 | } |
| ... | ... | @@ -17760,7 +18079,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 17760 | 18079 | } else if (extra.data.bits.has_addrspace_ref) blk: { |
| 17761 | 18080 | const addrspace_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); |
| 17762 | 18081 | extra_index += 1; |
| 17763 | | const addrspace_tv = sema.resolveInstConst(block, addrspace_src, addrspace_ref) catch |err| switch (err) { |
| 18082 | const addrspace_tv = sema.resolveInstConst(block, addrspace_src, addrspace_ref, "addrespace must be comptime known") catch |err| switch (err) { |
| 17764 | 18083 | error.GenericPoison => { |
| 17765 | 18084 | break :blk null; |
| 17766 | 18085 | }, |
| ... | ... | @@ -17775,7 +18094,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 17775 | 18094 | const body = sema.code.extra[extra_index..][0..body_len]; |
| 17776 | 18095 | extra_index += body.len; |
| 17777 | 18096 | |
| 17778 | | const val = try sema.resolveGenericBody(block, section_src, body, inst, Type.initTag(.const_slice_u8)); |
| 18097 | const val = try sema.resolveGenericBody(block, section_src, body, inst, Type.initTag(.const_slice_u8), "linksection must be comptime known"); |
| 17779 | 18098 | if (val.tag() == .generic_poison) { |
| 17780 | 18099 | break :blk FuncLinkSection{ .generic = {} }; |
| 17781 | 18100 | } |
| ... | ... | @@ -17784,7 +18103,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 17784 | 18103 | } else if (extra.data.bits.has_section_ref) blk: { |
| 17785 | 18104 | const section_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); |
| 17786 | 18105 | extra_index += 1; |
| 17787 | | const section_tv = sema.resolveInstConst(block, section_src, section_ref) catch |err| switch (err) { |
| 18106 | const section_tv = sema.resolveInstConst(block, section_src, section_ref, "linksection must be comptime known") catch |err| switch (err) { |
| 17788 | 18107 | error.GenericPoison => { |
| 17789 | 18108 | break :blk FuncLinkSection{ .generic = {} }; |
| 17790 | 18109 | }, |
| ... | ... | @@ -17801,7 +18120,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 17801 | 18120 | extra_index += body.len; |
| 17802 | 18121 | |
| 17803 | 18122 | const cc_ty = try sema.getBuiltinType(block, addrspace_src, "CallingConvention"); |
| 17804 | | const val = try sema.resolveGenericBody(block, cc_src, body, inst, cc_ty); |
| 18123 | const val = try sema.resolveGenericBody(block, cc_src, body, inst, cc_ty, "calling convention must be comptime known"); |
| 17805 | 18124 | if (val.tag() == .generic_poison) { |
| 17806 | 18125 | break :blk null; |
| 17807 | 18126 | } |
| ... | ... | @@ -17809,7 +18128,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 17809 | 18128 | } else if (extra.data.bits.has_cc_ref) blk: { |
| 17810 | 18129 | const cc_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); |
| 17811 | 18130 | extra_index += 1; |
| 17812 | | const cc_tv = sema.resolveInstConst(block, cc_src, cc_ref) catch |err| switch (err) { |
| 18131 | const cc_tv = sema.resolveInstConst(block, cc_src, cc_ref, "calling convention must be comptime known") catch |err| switch (err) { |
| 17813 | 18132 | error.GenericPoison => { |
| 17814 | 18133 | break :blk null; |
| 17815 | 18134 | }, |
| ... | ... | @@ -17824,14 +18143,14 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 17824 | 18143 | const body = sema.code.extra[extra_index..][0..body_len]; |
| 17825 | 18144 | extra_index += body.len; |
| 17826 | 18145 | |
| 17827 | | const val = try sema.resolveGenericBody(block, ret_src, body, inst, Type.type); |
| 18146 | const val = try sema.resolveGenericBody(block, ret_src, body, inst, Type.type, "return type must be comptime known"); |
| 17828 | 18147 | var buffer: Value.ToTypeBuffer = undefined; |
| 17829 | 18148 | const ty = try val.toType(&buffer).copy(sema.arena); |
| 17830 | 18149 | break :blk ty; |
| 17831 | 18150 | } else if (extra.data.bits.has_ret_ty_ref) blk: { |
| 17832 | 18151 | const ret_ty_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); |
| 17833 | 18152 | extra_index += 1; |
| 17834 | | const ret_ty_tv = sema.resolveInstConst(block, ret_src, ret_ty_ref) catch |err| switch (err) { |
| 18153 | const ret_ty_tv = sema.resolveInstConst(block, ret_src, ret_ty_ref, "return type must be comptime known") catch |err| switch (err) { |
| 17835 | 18154 | error.GenericPoison => { |
| 17836 | 18155 | break :blk Type.initTag(.generic_poison); |
| 17837 | 18156 | }, |
| ... | ... | @@ -17849,7 +18168,6 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 17849 | 18168 | } else 0; |
| 17850 | 18169 | |
| 17851 | 18170 | var src_locs: Zir.Inst.Func.SrcLocs = undefined; |
| 17852 | | const has_body = extra.data.body_len != 0; |
| 17853 | 18171 | if (has_body) { |
| 17854 | 18172 | extra_index += extra.data.body_len; |
| 17855 | 18173 | src_locs = sema.code.extraData(Zir.Inst.Func.SrcLocs, extra_index).data; |
| ... | ... | @@ -17886,7 +18204,7 @@ fn zirCUndef( |
| 17886 | 18204 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; |
| 17887 | 18205 | const src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node }; |
| 17888 | 18206 | |
| 17889 | | const name = try sema.resolveConstString(block, src, extra.operand); |
| 18207 | const name = try sema.resolveConstString(block, src, extra.operand, "name of macro being undefined must be comptime known"); |
| 17890 | 18208 | try block.c_import_buf.?.writer().print("#undefine {s}\n", .{name}); |
| 17891 | 18209 | return Air.Inst.Ref.void_value; |
| 17892 | 18210 | } |
| ... | ... | @@ -17899,7 +18217,7 @@ fn zirCInclude( |
| 17899 | 18217 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; |
| 17900 | 18218 | const src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node }; |
| 17901 | 18219 | |
| 17902 | | const name = try sema.resolveConstString(block, src, extra.operand); |
| 18220 | const name = try sema.resolveConstString(block, src, extra.operand, "path being included must be comptime known"); |
| 17903 | 18221 | try block.c_import_buf.?.writer().print("#include <{s}>\n", .{name}); |
| 17904 | 18222 | return Air.Inst.Ref.void_value; |
| 17905 | 18223 | } |
| ... | ... | @@ -17913,10 +18231,10 @@ fn zirCDefine( |
| 17913 | 18231 | const name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node }; |
| 17914 | 18232 | const val_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node }; |
| 17915 | 18233 | |
| 17916 | | const name = try sema.resolveConstString(block, name_src, extra.lhs); |
| 18234 | const name = try sema.resolveConstString(block, name_src, extra.lhs, "name of macro being undefined must be comptime known"); |
| 17917 | 18235 | const rhs = try sema.resolveInst(extra.rhs); |
| 17918 | 18236 | if (sema.typeOf(rhs).zigTypeTag() != .Void) { |
| 17919 | | const value = try sema.resolveConstString(block, val_src, extra.rhs); |
| 18237 | const value = try sema.resolveConstString(block, val_src, extra.rhs, "value of macro being undefined must be comptime known"); |
| 17920 | 18238 | try block.c_import_buf.?.writer().print("#define {s} {s}\n", .{ name, value }); |
| 17921 | 18239 | } else { |
| 17922 | 18240 | try block.c_import_buf.?.writer().print("#define {s}\n", .{name}); |
| ... | ... | @@ -17937,8 +18255,8 @@ fn zirWasmMemorySize( |
| 17937 | 18255 | return sema.fail(block, builtin_src, "builtin @wasmMemorySize is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)}); |
| 17938 | 18256 | } |
| 17939 | 18257 | |
| 17940 | | const index = @intCast(u32, try sema.resolveInt(block, index_src, extra.operand, Type.u32)); |
| 17941 | | try sema.requireRuntimeBlock(block, builtin_src); |
| 18258 | const index = @intCast(u32, try sema.resolveInt(block, index_src, extra.operand, Type.u32, "wasm memory size index must be comptime known")); |
| 18259 | try sema.requireRuntimeBlock(block, builtin_src, null); |
| 17942 | 18260 | return block.addInst(.{ |
| 17943 | 18261 | .tag = .wasm_memory_size, |
| 17944 | 18262 | .data = .{ .pl_op = .{ |
| ... | ... | @@ -17962,10 +18280,10 @@ fn zirWasmMemoryGrow( |
| 17962 | 18280 | return sema.fail(block, builtin_src, "builtin @wasmMemoryGrow is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)}); |
| 17963 | 18281 | } |
| 17964 | 18282 | |
| 17965 | | const index = @intCast(u32, try sema.resolveInt(block, index_src, extra.lhs, Type.u32)); |
| 18283 | const index = @intCast(u32, try sema.resolveInt(block, index_src, extra.lhs, Type.u32, "wasm memory size index must be comptime known")); |
| 17966 | 18284 | const delta = try sema.coerce(block, Type.u32, try sema.resolveInst(extra.rhs), delta_src); |
| 17967 | 18285 | |
| 17968 | | try sema.requireRuntimeBlock(block, builtin_src); |
| 18286 | try sema.requireRuntimeBlock(block, builtin_src, null); |
| 17969 | 18287 | return block.addInst(.{ |
| 17970 | 18288 | .tag = .wasm_memory_grow, |
| 17971 | 18289 | .data = .{ .pl_op = .{ |
| ... | ... | @@ -17990,15 +18308,15 @@ fn zirPrefetch( |
| 17990 | 18308 | const target = sema.mod.getTarget(); |
| 17991 | 18309 | |
| 17992 | 18310 | const rw = try sema.fieldVal(block, opts_src, options, "rw", opts_src); |
| 17993 | | const rw_val = try sema.resolveConstValue(block, opts_src, rw); |
| 18311 | const rw_val = try sema.resolveConstValue(block, opts_src, rw, "prefetch read/write must be comptime known"); |
| 17994 | 18312 | const rw_tag = rw_val.toEnum(std.builtin.PrefetchOptions.Rw); |
| 17995 | 18313 | |
| 17996 | 18314 | const locality = try sema.fieldVal(block, opts_src, options, "locality", opts_src); |
| 17997 | | const locality_val = try sema.resolveConstValue(block, opts_src, locality); |
| 18315 | const locality_val = try sema.resolveConstValue(block, opts_src, locality, "prefetch locality must be comptime known"); |
| 17998 | 18316 | const locality_int = @intCast(u2, locality_val.toUnsignedInt(target)); |
| 17999 | 18317 | |
| 18000 | 18318 | const cache = try sema.fieldVal(block, opts_src, options, "cache", opts_src); |
| 18001 | | const cache_val = try sema.resolveConstValue(block, opts_src, cache); |
| 18319 | const cache_val = try sema.resolveConstValue(block, opts_src, cache, "prefetch cache must be comptime known"); |
| 18002 | 18320 | const cache_tag = cache_val.toEnum(std.builtin.PrefetchOptions.Cache); |
| 18003 | 18321 | |
| 18004 | 18322 | if (!block.is_comptime) { |
| ... | ... | @@ -18035,16 +18353,16 @@ fn zirBuiltinExtern( |
| 18035 | 18353 | const options = try sema.coerce(block, extern_options_ty, options_inst, options_src); |
| 18036 | 18354 | |
| 18037 | 18355 | const name = try sema.fieldVal(block, options_src, options, "name", options_src); |
| 18038 | | const name_val = try sema.resolveConstValue(block, options_src, name); |
| 18356 | const name_val = try sema.resolveConstValue(block, options_src, name, "name of the extern symbol must be comptime known"); |
| 18039 | 18357 | |
| 18040 | 18358 | const library_name_inst = try sema.fieldVal(block, options_src, options, "library_name", options_src); |
| 18041 | | const library_name_val = try sema.resolveConstValue(block, options_src, library_name_inst); |
| 18359 | const library_name_val = try sema.resolveConstValue(block, options_src, library_name_inst, "library in which extern symbol is must be comptime known"); |
| 18042 | 18360 | |
| 18043 | 18361 | const linkage = try sema.fieldVal(block, options_src, options, "linkage", options_src); |
| 18044 | | const linkage_val = try sema.resolveConstValue(block, options_src, linkage); |
| 18362 | const linkage_val = try sema.resolveConstValue(block, options_src, linkage, "linkage of the extern symbol must be comptime known"); |
| 18045 | 18363 | |
| 18046 | 18364 | const is_thread_local = try sema.fieldVal(block, options_src, options, "is_thread_local", options_src); |
| 18047 | | const is_thread_local_val = try sema.resolveConstValue(block, options_src, is_thread_local); |
| 18365 | const is_thread_local_val = try sema.resolveConstValue(block, options_src, is_thread_local, "threadlocality of the extern symbol must be comptime known"); |
| 18048 | 18366 | |
| 18049 | 18367 | var library_name: ?[]const u8 = null; |
| 18050 | 18368 | if (!library_name_val.isNull()) { |
| ... | ... | @@ -18121,19 +18439,30 @@ fn zirBuiltinExtern( |
| 18121 | 18439 | new_decl.value_arena = arena_state; |
| 18122 | 18440 | |
| 18123 | 18441 | const ref = try sema.analyzeDeclRef(new_decl_index); |
| 18124 | | try sema.requireRuntimeBlock(block, src); |
| 18442 | try sema.requireRuntimeBlock(block, src, null); |
| 18125 | 18443 | return block.addBitCast(ty, ref); |
| 18126 | 18444 | } |
| 18127 | 18445 | |
| 18446 | /// Asserts that the block is not comptime. |
| 18128 | 18447 | fn requireFunctionBlock(sema: *Sema, block: *Block, src: LazySrcLoc) !void { |
| 18448 | assert(!block.is_comptime); |
| 18129 | 18449 | if (sema.func == null and !block.is_typeof and !block.is_coerce_result_ptr) { |
| 18130 | 18450 | return sema.fail(block, src, "instruction illegal outside function body", .{}); |
| 18131 | 18451 | } |
| 18132 | 18452 | } |
| 18133 | 18453 | |
| 18134 | | fn requireRuntimeBlock(sema: *Sema, block: *Block, src: LazySrcLoc) !void { |
| 18454 | fn requireRuntimeBlock(sema: *Sema, block: *Block, src: LazySrcLoc, runtime_src: ?LazySrcLoc) !void { |
| 18135 | 18455 | if (block.is_comptime) { |
| 18136 | | return sema.failWithNeededComptime(block, src); |
| 18456 | const msg = msg: { |
| 18457 | const msg = try sema.errMsg(block, src, "unable to evalutate comptime expression", .{}); |
| 18458 | errdefer msg.destroy(sema.gpa); |
| 18459 | |
| 18460 | if (runtime_src) |some| { |
| 18461 | try sema.errNote(block, some, msg, "operation is runtime due to this operand", .{}); |
| 18462 | } |
| 18463 | break :msg msg; |
| 18464 | }; |
| 18465 | return sema.failWithOwnedErrorMsg(block, msg); |
| 18137 | 18466 | } |
| 18138 | 18467 | try sema.requireFunctionBlock(block, src); |
| 18139 | 18468 | } |
| ... | ... | @@ -18337,6 +18666,8 @@ const ExternPosition = enum { |
| 18337 | 18666 | other, |
| 18338 | 18667 | }; |
| 18339 | 18668 | |
| 18669 | /// Returns true if `ty` is allowed in extern types. |
| 18670 | /// Does *NOT* require `ty` to be resolved in any way. |
| 18340 | 18671 | fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileError!bool { |
| 18341 | 18672 | switch (ty.zigTypeTag()) { |
| 18342 | 18673 | .Type, |
| ... | ... | @@ -18350,7 +18681,7 @@ fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileEr |
| 18350 | 18681 | .BoundFn, |
| 18351 | 18682 | .Frame, |
| 18352 | 18683 | => return false, |
| 18353 | | .Void => return position == .union_field, |
| 18684 | .Void => return position == .union_field or position == .ret_ty, |
| 18354 | 18685 | .NoReturn => return position == .ret_ty, |
| 18355 | 18686 | .Opaque, |
| 18356 | 18687 | .Bool, |
| ... | ... | @@ -18362,7 +18693,7 @@ fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileEr |
| 18362 | 18693 | 8, 16, 32, 64, 128 => return true, |
| 18363 | 18694 | else => return false, |
| 18364 | 18695 | }, |
| 18365 | | .Fn => return !ty.fnCallingConventionAllowsZigTypes(), |
| 18696 | .Fn => return !Type.fnCallingConventionAllowsZigTypes(ty.fnCallingConvention()), |
| 18366 | 18697 | .Enum => { |
| 18367 | 18698 | var buf: Type.Payload.Bits = undefined; |
| 18368 | 18699 | return sema.validateExternType(ty.intTagType(&buf), position); |
| ... | ... | @@ -18433,9 +18764,9 @@ fn explainWhyTypeIsNotExtern( |
| 18433 | 18764 | .Union => try mod.errNoteNonLazy(src_loc, msg, "only unions with packed or extern layout are extern compatible", .{}), |
| 18434 | 18765 | .Array => { |
| 18435 | 18766 | if (position == .ret_ty) { |
| 18436 | | try mod.errNoteNonLazy(src_loc, msg, "arrays are not allowed as a return type", .{}); |
| 18767 | return mod.errNoteNonLazy(src_loc, msg, "arrays are not allowed as a return type", .{}); |
| 18437 | 18768 | } else if (position == .param_ty) { |
| 18438 | | try mod.errNoteNonLazy(src_loc, msg, "arrays are not allowed as a parameter type", .{}); |
| 18769 | return mod.errNoteNonLazy(src_loc, msg, "arrays are not allowed as a parameter type", .{}); |
| 18439 | 18770 | } |
| 18440 | 18771 | try sema.explainWhyTypeIsNotExtern(block, src, msg, src_loc, ty.elemType2(), position); |
| 18441 | 18772 | }, |
| ... | ... | @@ -18972,7 +19303,7 @@ fn fieldPtr( |
| 18972 | 19303 | }), |
| 18973 | 19304 | ); |
| 18974 | 19305 | } |
| 18975 | | try sema.requireRuntimeBlock(block, src); |
| 19306 | try sema.requireRuntimeBlock(block, src, null); |
| 18976 | 19307 | |
| 18977 | 19308 | return block.addTyOp(.ptr_slice_ptr_ptr, result_ty, inner_ptr); |
| 18978 | 19309 | } else if (mem.eql(u8, field_name, "len")) { |
| ... | ... | @@ -18992,7 +19323,7 @@ fn fieldPtr( |
| 18992 | 19323 | }), |
| 18993 | 19324 | ); |
| 18994 | 19325 | } |
| 18995 | | try sema.requireRuntimeBlock(block, src); |
| 19326 | try sema.requireRuntimeBlock(block, src, null); |
| 18996 | 19327 | |
| 18997 | 19328 | return block.addTyOp(.ptr_slice_len_ptr, result_ty, inner_ptr); |
| 18998 | 19329 | } else { |
| ... | ... | @@ -19005,7 +19336,7 @@ fn fieldPtr( |
| 19005 | 19336 | } |
| 19006 | 19337 | }, |
| 19007 | 19338 | .Type => { |
| 19008 | | _ = try sema.resolveConstValue(block, object_ptr_src, object_ptr); |
| 19339 | _ = try sema.resolveConstValue(block, .unneeded, object_ptr, undefined); |
| 19009 | 19340 | const result = try sema.analyzeLoad(block, src, object_ptr, object_ptr_src); |
| 19010 | 19341 | const inner = if (is_pointer_to) |
| 19011 | 19342 | try sema.analyzeLoad(block, src, result, object_ptr_src) |
| ... | ... | @@ -19238,7 +19569,7 @@ fn finishFieldCallBind( |
| 19238 | 19569 | return sema.analyzeLoad(block, src, pointer, src); |
| 19239 | 19570 | } |
| 19240 | 19571 | |
| 19241 | | try sema.requireRuntimeBlock(block, src); |
| 19572 | try sema.requireRuntimeBlock(block, src, null); |
| 19242 | 19573 | const ptr_inst = try block.addStructFieldPtr(object_ptr, field_index, ptr_field_ty); |
| 19243 | 19574 | return sema.analyzeLoad(block, src, ptr_inst, src); |
| 19244 | 19575 | } |
| ... | ... | @@ -19425,7 +19756,7 @@ fn structFieldPtrByIndex( |
| 19425 | 19756 | ); |
| 19426 | 19757 | } |
| 19427 | 19758 | |
| 19428 | | try sema.requireRuntimeBlock(block, src); |
| 19759 | try sema.requireRuntimeBlock(block, src, null); |
| 19429 | 19760 | return block.addStructFieldPtr(struct_ptr, field_index, ptr_field_ty); |
| 19430 | 19761 | } |
| 19431 | 19762 | |
| ... | ... | @@ -19469,7 +19800,7 @@ fn structFieldVal( |
| 19469 | 19800 | return sema.addConstant(field.ty, field_values[field_index]); |
| 19470 | 19801 | } |
| 19471 | 19802 | |
| 19472 | | try sema.requireRuntimeBlock(block, src); |
| 19803 | try sema.requireRuntimeBlock(block, src, null); |
| 19473 | 19804 | return block.addStructFieldVal(struct_byval, field_index, field.ty); |
| 19474 | 19805 | }, |
| 19475 | 19806 | else => unreachable, |
| ... | ... | @@ -19533,7 +19864,7 @@ fn tupleFieldValByIndex( |
| 19533 | 19864 | return sema.addConstant(field_ty, field_values[field_index]); |
| 19534 | 19865 | } |
| 19535 | 19866 | |
| 19536 | | try sema.requireRuntimeBlock(block, src); |
| 19867 | try sema.requireRuntimeBlock(block, src, null); |
| 19537 | 19868 | return block.addStructFieldVal(tuple_byval, field_index, field_ty); |
| 19538 | 19869 | } |
| 19539 | 19870 | |
| ... | ... | @@ -19597,7 +19928,7 @@ fn unionFieldPtr( |
| 19597 | 19928 | ); |
| 19598 | 19929 | } |
| 19599 | 19930 | |
| 19600 | | try sema.requireRuntimeBlock(block, src); |
| 19931 | try sema.requireRuntimeBlock(block, src, null); |
| 19601 | 19932 | return block.addStructFieldPtr(union_ptr, field_index, ptr_field_ty); |
| 19602 | 19933 | } |
| 19603 | 19934 | |
| ... | ... | @@ -19655,7 +19986,7 @@ fn unionFieldVal( |
| 19655 | 19986 | } |
| 19656 | 19987 | } |
| 19657 | 19988 | |
| 19658 | | try sema.requireRuntimeBlock(block, src); |
| 19989 | try sema.requireRuntimeBlock(block, src, null); |
| 19659 | 19990 | return block.addStructFieldVal(union_byval, field_index, field.ty); |
| 19660 | 19991 | } |
| 19661 | 19992 | |
| ... | ... | @@ -19684,7 +20015,7 @@ fn elemPtr( |
| 19684 | 20015 | // In all below cases, we have to deref the ptr operand to get the actual indexable pointer. |
| 19685 | 20016 | const indexable = try sema.analyzeLoad(block, indexable_ptr_src, indexable_ptr, indexable_ptr_src); |
| 19686 | 20017 | switch (indexable_ty.ptrSize()) { |
| 19687 | | .Slice => return sema.elemPtrSlice(block, indexable_ptr_src, indexable, elem_index_src, elem_index), |
| 20018 | .Slice => return sema.elemPtrSlice(block, src, indexable_ptr_src, indexable, elem_index_src, elem_index), |
| 19688 | 20019 | .Many, .C => { |
| 19689 | 20020 | const maybe_ptr_val = try sema.resolveDefinedValue(block, indexable_ptr_src, indexable); |
| 19690 | 20021 | const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index); |
| ... | ... | @@ -19698,19 +20029,19 @@ fn elemPtr( |
| 19698 | 20029 | }; |
| 19699 | 20030 | const result_ty = try sema.elemPtrType(indexable_ty, null); |
| 19700 | 20031 | |
| 19701 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 20032 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 19702 | 20033 | return block.addPtrElemPtr(indexable, elem_index, result_ty); |
| 19703 | 20034 | }, |
| 19704 | 20035 | .One => { |
| 19705 | 20036 | assert(indexable_ty.childType().zigTypeTag() == .Array); // Guaranteed by isIndexable |
| 19706 | | return sema.elemPtrArray(block, indexable_ptr_src, indexable, elem_index_src, elem_index, init); |
| 20037 | return sema.elemPtrArray(block, src, indexable_ptr_src, indexable, elem_index_src, elem_index, init); |
| 19707 | 20038 | }, |
| 19708 | 20039 | } |
| 19709 | 20040 | }, |
| 19710 | | .Array, .Vector => return sema.elemPtrArray(block, indexable_ptr_src, indexable_ptr, elem_index_src, elem_index, init), |
| 20041 | .Array, .Vector => return sema.elemPtrArray(block, src, indexable_ptr_src, indexable_ptr, elem_index_src, elem_index, init), |
| 19711 | 20042 | .Struct => { |
| 19712 | 20043 | // Tuple field access. |
| 19713 | | const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index); |
| 20044 | const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index, "tuple field access index must be comptime known"); |
| 19714 | 20045 | const index = @intCast(u32, index_val.toUnsignedInt(target)); |
| 19715 | 20046 | return sema.tupleFieldPtr(block, src, indexable_ptr, elem_index_src, index); |
| 19716 | 20047 | }, |
| ... | ... | @@ -19740,7 +20071,7 @@ fn elemVal( |
| 19740 | 20071 | |
| 19741 | 20072 | switch (indexable_ty.zigTypeTag()) { |
| 19742 | 20073 | .Pointer => switch (indexable_ty.ptrSize()) { |
| 19743 | | .Slice => return sema.elemValSlice(block, indexable_src, indexable, elem_index_src, elem_index), |
| 20074 | .Slice => return sema.elemValSlice(block, src, indexable_src, indexable, elem_index_src, elem_index), |
| 19744 | 20075 | .Many, .C => { |
| 19745 | 20076 | const maybe_indexable_val = try sema.resolveDefinedValue(block, indexable_src, indexable); |
| 19746 | 20077 | const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index); |
| ... | ... | @@ -19756,7 +20087,7 @@ fn elemVal( |
| 19756 | 20087 | break :rs indexable_src; |
| 19757 | 20088 | }; |
| 19758 | 20089 | |
| 19759 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 20090 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 19760 | 20091 | return block.addBinOp(.ptr_elem_val, indexable, elem_index); |
| 19761 | 20092 | }, |
| 19762 | 20093 | .One => { |
| ... | ... | @@ -19765,14 +20096,14 @@ fn elemVal( |
| 19765 | 20096 | return sema.analyzeLoad(block, indexable_src, elem_ptr, elem_index_src); |
| 19766 | 20097 | }, |
| 19767 | 20098 | }, |
| 19768 | | .Array => return elemValArray(sema, block, indexable_src, indexable, elem_index_src, elem_index), |
| 20099 | .Array => return sema.elemValArray(block, src, indexable_src, indexable, elem_index_src, elem_index), |
| 19769 | 20100 | .Vector => { |
| 19770 | 20101 | // TODO: If the index is a vector, the result should be a vector. |
| 19771 | | return elemValArray(sema, block, indexable_src, indexable, elem_index_src, elem_index); |
| 20102 | return sema.elemValArray(block, src, indexable_src, indexable, elem_index_src, elem_index); |
| 19772 | 20103 | }, |
| 19773 | 20104 | .Struct => { |
| 19774 | 20105 | // Tuple field access. |
| 19775 | | const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index); |
| 20106 | const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index, "tuple field access index must be comptime known"); |
| 19776 | 20107 | const index = @intCast(u32, index_val.toUnsignedInt(target)); |
| 19777 | 20108 | return tupleField(sema, block, indexable_src, indexable, elem_index_src, index); |
| 19778 | 20109 | }, |
| ... | ... | @@ -19850,7 +20181,7 @@ fn tupleFieldPtr( |
| 19850 | 20181 | |
| 19851 | 20182 | try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_ptr_src); |
| 19852 | 20183 | |
| 19853 | | try sema.requireRuntimeBlock(block, tuple_ptr_src); |
| 20184 | try sema.requireRuntimeBlock(block, tuple_ptr_src, null); |
| 19854 | 20185 | return block.addStructFieldPtr(tuple_ptr, field_index, ptr_field_ty); |
| 19855 | 20186 | } |
| 19856 | 20187 | |
| ... | ... | @@ -19890,13 +20221,14 @@ fn tupleField( |
| 19890 | 20221 | |
| 19891 | 20222 | try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_src); |
| 19892 | 20223 | |
| 19893 | | try sema.requireRuntimeBlock(block, tuple_src); |
| 20224 | try sema.requireRuntimeBlock(block, tuple_src, null); |
| 19894 | 20225 | return block.addStructFieldVal(tuple, field_index, field_ty); |
| 19895 | 20226 | } |
| 19896 | 20227 | |
| 19897 | 20228 | fn elemValArray( |
| 19898 | 20229 | sema: *Sema, |
| 19899 | 20230 | block: *Block, |
| 20231 | src: LazySrcLoc, |
| 19900 | 20232 | array_src: LazySrcLoc, |
| 19901 | 20233 | array: Air.Inst.Ref, |
| 19902 | 20234 | elem_index_src: LazySrcLoc, |
| ... | ... | @@ -19943,7 +20275,7 @@ fn elemValArray( |
| 19943 | 20275 | try sema.validateRuntimeElemAccess(block, elem_index_src, elem_ty, array_ty, array_src); |
| 19944 | 20276 | |
| 19945 | 20277 | const runtime_src = if (maybe_undef_array_val != null) elem_index_src else array_src; |
| 19946 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 20278 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 19947 | 20279 | if (block.wantSafety()) { |
| 19948 | 20280 | // Runtime check is only needed if unable to comptime check |
| 19949 | 20281 | if (maybe_index_val == null) { |
| ... | ... | @@ -19958,6 +20290,7 @@ fn elemValArray( |
| 19958 | 20290 | fn elemPtrArray( |
| 19959 | 20291 | sema: *Sema, |
| 19960 | 20292 | block: *Block, |
| 20293 | src: LazySrcLoc, |
| 19961 | 20294 | array_ptr_src: LazySrcLoc, |
| 19962 | 20295 | array_ptr: Air.Inst.Ref, |
| 19963 | 20296 | elem_index_src: LazySrcLoc, |
| ... | ... | @@ -20003,7 +20336,7 @@ fn elemPtrArray( |
| 20003 | 20336 | } |
| 20004 | 20337 | |
| 20005 | 20338 | const runtime_src = if (maybe_undef_array_ptr_val != null) elem_index_src else array_ptr_src; |
| 20006 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 20339 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 20007 | 20340 | |
| 20008 | 20341 | // Runtime check is only needed if unable to comptime check. |
| 20009 | 20342 | if (block.wantSafety() and offset == null) { |
| ... | ... | @@ -20018,6 +20351,7 @@ fn elemPtrArray( |
| 20018 | 20351 | fn elemValSlice( |
| 20019 | 20352 | sema: *Sema, |
| 20020 | 20353 | block: *Block, |
| 20354 | src: LazySrcLoc, |
| 20021 | 20355 | slice_src: LazySrcLoc, |
| 20022 | 20356 | slice: Air.Inst.Ref, |
| 20023 | 20357 | elem_index_src: LazySrcLoc, |
| ... | ... | @@ -20057,7 +20391,7 @@ fn elemValSlice( |
| 20057 | 20391 | |
| 20058 | 20392 | try sema.validateRuntimeElemAccess(block, elem_index_src, elem_ty, slice_ty, slice_src); |
| 20059 | 20393 | |
| 20060 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 20394 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 20061 | 20395 | if (block.wantSafety()) { |
| 20062 | 20396 | const len_inst = if (maybe_slice_val) |slice_val| |
| 20063 | 20397 | try sema.addIntUnsigned(Type.usize, slice_val.sliceLen(sema.mod)) |
| ... | ... | @@ -20073,6 +20407,7 @@ fn elemValSlice( |
| 20073 | 20407 | fn elemPtrSlice( |
| 20074 | 20408 | sema: *Sema, |
| 20075 | 20409 | block: *Block, |
| 20410 | src: LazySrcLoc, |
| 20076 | 20411 | slice_src: LazySrcLoc, |
| 20077 | 20412 | slice: Air.Inst.Ref, |
| 20078 | 20413 | elem_index_src: LazySrcLoc, |
| ... | ... | @@ -20113,7 +20448,7 @@ fn elemPtrSlice( |
| 20113 | 20448 | try sema.validateRuntimeElemAccess(block, elem_index_src, elem_ptr_ty, slice_ty, slice_src); |
| 20114 | 20449 | |
| 20115 | 20450 | const runtime_src = if (maybe_undef_slice_val != null) elem_index_src else slice_src; |
| 20116 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 20451 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 20117 | 20452 | if (block.wantSafety()) { |
| 20118 | 20453 | const len_inst = len: { |
| 20119 | 20454 | if (maybe_undef_slice_val) |slice_val| |
| ... | ... | @@ -20177,7 +20512,7 @@ fn coerceExtra( |
| 20177 | 20512 | // Keep the comptime Value representation; take the new type. |
| 20178 | 20513 | return sema.addConstant(dest_ty, val); |
| 20179 | 20514 | } |
| 20180 | | try sema.requireRuntimeBlock(block, inst_src); |
| 20515 | try sema.requireRuntimeBlock(block, inst_src, null); |
| 20181 | 20516 | return block.addBitCast(dest_ty, inst); |
| 20182 | 20517 | } |
| 20183 | 20518 | |
| ... | ... | @@ -20222,7 +20557,7 @@ fn coerceExtra( |
| 20222 | 20557 | |
| 20223 | 20558 | // Function body to function pointer. |
| 20224 | 20559 | if (inst_ty.zigTypeTag() == .Fn) { |
| 20225 | | const fn_val = try sema.resolveConstValue(block, inst_src, inst); |
| 20560 | const fn_val = try sema.resolveConstValue(block, .unneeded, inst, undefined); |
| 20226 | 20561 | const fn_decl = fn_val.castTag(.function).?.data.owner_decl; |
| 20227 | 20562 | const inst_as_ptr = try sema.analyzeDeclRef(fn_decl); |
| 20228 | 20563 | return sema.coerce(block, dest_ty, inst_as_ptr, inst_src); |
| ... | ... | @@ -20489,7 +20824,7 @@ fn coerceExtra( |
| 20489 | 20824 | // small enough unsigned ints can get casted to large enough signed ints |
| 20490 | 20825 | (dst_info.signedness == .signed and dst_info.bits > src_info.bits)) |
| 20491 | 20826 | { |
| 20492 | | try sema.requireRuntimeBlock(block, inst_src); |
| 20827 | try sema.requireRuntimeBlock(block, inst_src, null); |
| 20493 | 20828 | return block.addTyOp(.intcast, dest_ty, inst); |
| 20494 | 20829 | } |
| 20495 | 20830 | }, |
| ... | ... | @@ -20500,7 +20835,7 @@ fn coerceExtra( |
| 20500 | 20835 | }, |
| 20501 | 20836 | .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag()) { |
| 20502 | 20837 | .ComptimeFloat => { |
| 20503 | | const val = try sema.resolveConstValue(block, inst_src, inst); |
| 20838 | const val = try sema.resolveConstValue(block, .unneeded, inst, undefined); |
| 20504 | 20839 | const result_val = try val.floatCast(sema.arena, dest_ty, target); |
| 20505 | 20840 | return try sema.addConstant(dest_ty, result_val); |
| 20506 | 20841 | }, |
| ... | ... | @@ -20516,13 +20851,15 @@ fn coerceExtra( |
| 20516 | 20851 | ); |
| 20517 | 20852 | } |
| 20518 | 20853 | return try sema.addConstant(dest_ty, result_val); |
| 20854 | } else if (dest_ty.zigTypeTag() == .ComptimeFloat) { |
| 20855 | return sema.failWithNeededComptime(block, inst_src, "value being casted to 'comptime_float' must be comptime known"); |
| 20519 | 20856 | } |
| 20520 | 20857 | |
| 20521 | 20858 | // float widening |
| 20522 | 20859 | const src_bits = inst_ty.floatBits(target); |
| 20523 | 20860 | const dst_bits = dest_ty.floatBits(target); |
| 20524 | 20861 | if (dst_bits >= src_bits) { |
| 20525 | | try sema.requireRuntimeBlock(block, inst_src); |
| 20862 | try sema.requireRuntimeBlock(block, inst_src, null); |
| 20526 | 20863 | return block.addTyOp(.fpext, dest_ty, inst); |
| 20527 | 20864 | } |
| 20528 | 20865 | }, |
| ... | ... | @@ -20549,7 +20886,7 @@ fn coerceExtra( |
| 20549 | 20886 | .Enum => switch (inst_ty.zigTypeTag()) { |
| 20550 | 20887 | .EnumLiteral => { |
| 20551 | 20888 | // enum literal to enum |
| 20552 | | const val = try sema.resolveConstValue(block, inst_src, inst); |
| 20889 | const val = try sema.resolveConstValue(block, .unneeded, inst, undefined); |
| 20553 | 20890 | const bytes = val.castTag(.enum_literal).?.data; |
| 20554 | 20891 | const field_index = dest_ty.enumFieldIndex(bytes) orelse { |
| 20555 | 20892 | const msg = msg: { |
| ... | ... | @@ -20956,17 +21293,17 @@ const InMemoryCoercionResult = union(enum) { |
| 20956 | 21293 | } |
| 20957 | 21294 | } |
| 20958 | 21295 | if (!actual_noalias) { |
| 20959 | | try sema.errNote(block, src, msg, "regular paramter {d} cannot cast into a noalias paramter", .{index}); |
| 21296 | try sema.errNote(block, src, msg, "regular parameter {d} cannot cast into a noalias parameter", .{index}); |
| 20960 | 21297 | } else { |
| 20961 | | try sema.errNote(block, src, msg, "noalias paramter {d} cannot cast into a regular paramter", .{index}); |
| 21298 | try sema.errNote(block, src, msg, "noalias parameter {d} cannot cast into a regular parameter", .{index}); |
| 20962 | 21299 | } |
| 20963 | 21300 | break; |
| 20964 | 21301 | }, |
| 20965 | 21302 | .fn_param_comptime => |param| { |
| 20966 | 21303 | if (param.wanted) { |
| 20967 | | try sema.errNote(block, src, msg, "non-comptime paramter {d} cannot cast into a comptime paramter", .{param.index}); |
| 21304 | try sema.errNote(block, src, msg, "non-comptime parameter {d} cannot cast into a comptime parameter", .{param.index}); |
| 20968 | 21305 | } else { |
| 20969 | | try sema.errNote(block, src, msg, "comptime paramter {d} cannot cast into a non-comptime paramter", .{param.index}); |
| 21306 | try sema.errNote(block, src, msg, "comptime parameter {d} cannot cast into a non-comptime parameter", .{param.index}); |
| 20970 | 21307 | } |
| 20971 | 21308 | break; |
| 20972 | 21309 | }, |
| ... | ... | @@ -21712,7 +22049,12 @@ fn storePtr2( |
| 21712 | 22049 | return; |
| 21713 | 22050 | } |
| 21714 | 22051 | |
| 21715 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 22052 | if (block.is_comptime) { |
| 22053 | // TODO ideally this would tell why the block is comptime |
| 22054 | return sema.fail(block, ptr_src, "cannot store to runtime value in comptime block", .{}); |
| 22055 | } |
| 22056 | |
| 22057 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 21716 | 22058 | try sema.queueFullTypeResolution(elem_ty); |
| 21717 | 22059 | if (is_ret) { |
| 21718 | 22060 | _ = try block.addBinOp(.store, ptr, operand); |
| ... | ... | @@ -22644,7 +22986,7 @@ fn bitCast( |
| 22644 | 22986 | const result_val = try sema.bitCastVal(block, inst_src, val, old_ty, dest_ty, 0); |
| 22645 | 22987 | return sema.addConstant(dest_ty, result_val); |
| 22646 | 22988 | } |
| 22647 | | try sema.requireRuntimeBlock(block, inst_src); |
| 22989 | try sema.requireRuntimeBlock(block, inst_src, null); |
| 22648 | 22990 | return block.addBitCast(dest_ty, inst); |
| 22649 | 22991 | } |
| 22650 | 22992 | |
| ... | ... | @@ -22727,7 +23069,7 @@ fn coerceArrayPtrToSlice( |
| 22727 | 23069 | }); |
| 22728 | 23070 | return sema.addConstant(dest_ty, slice_val); |
| 22729 | 23071 | } |
| 22730 | | try sema.requireRuntimeBlock(block, inst_src); |
| 23072 | try sema.requireRuntimeBlock(block, inst_src, null); |
| 22731 | 23073 | return block.addTyOp(.array_to_slice, dest_ty, inst); |
| 22732 | 23074 | } |
| 22733 | 23075 | |
| ... | ... | @@ -22743,7 +23085,7 @@ fn coerceCompatiblePtrs( |
| 22743 | 23085 | // The comptime Value representation is compatible with both types. |
| 22744 | 23086 | return sema.addConstant(dest_ty, val); |
| 22745 | 23087 | } |
| 22746 | | try sema.requireRuntimeBlock(block, inst_src); |
| 23088 | try sema.requireRuntimeBlock(block, inst_src, null); |
| 22747 | 23089 | return sema.bitCast(block, dest_ty, inst, inst_src); |
| 22748 | 23090 | } |
| 22749 | 23091 | |
| ... | ... | @@ -22807,7 +23149,7 @@ fn coerceEnumToUnion( |
| 22807 | 23149 | })); |
| 22808 | 23150 | } |
| 22809 | 23151 | |
| 22810 | | try sema.requireRuntimeBlock(block, inst_src); |
| 23152 | try sema.requireRuntimeBlock(block, inst_src, null); |
| 22811 | 23153 | |
| 22812 | 23154 | if (tag_ty.isNonexhaustiveEnum()) { |
| 22813 | 23155 | const msg = msg: { |
| ... | ... | @@ -22947,7 +23289,7 @@ fn coerceArrayLike( |
| 22947 | 23289 | // These types share the same comptime value representation. |
| 22948 | 23290 | return sema.addConstant(dest_ty, inst_val); |
| 22949 | 23291 | } |
| 22950 | | try sema.requireRuntimeBlock(block, inst_src); |
| 23292 | try sema.requireRuntimeBlock(block, inst_src, null); |
| 22951 | 23293 | return block.addBitCast(dest_ty, inst); |
| 22952 | 23294 | } |
| 22953 | 23295 | |
| ... | ... | @@ -22960,8 +23302,9 @@ fn coerceArrayLike( |
| 22960 | 23302 | Type.usize, |
| 22961 | 23303 | try Value.Tag.int_u64.create(sema.arena, i), |
| 22962 | 23304 | ); |
| 23305 | const src = inst_src; // TODO better source location |
| 22963 | 23306 | const elem_src = inst_src; // TODO better source location |
| 22964 | | const elem_ref = try elemValArray(sema, block, inst_src, inst, elem_src, index_ref); |
| 23307 | const elem_ref = try sema.elemValArray(block, src, inst_src, inst, elem_src, index_ref); |
| 22965 | 23308 | const coerced = try sema.coerce(block, dest_elem_ty, elem_ref, elem_src); |
| 22966 | 23309 | element_refs[i] = coerced; |
| 22967 | 23310 | if (runtime_src == null) { |
| ... | ... | @@ -22974,7 +23317,7 @@ fn coerceArrayLike( |
| 22974 | 23317 | } |
| 22975 | 23318 | |
| 22976 | 23319 | if (runtime_src) |rs| { |
| 22977 | | try sema.requireRuntimeBlock(block, rs); |
| 23320 | try sema.requireRuntimeBlock(block, inst_src, rs); |
| 22978 | 23321 | return block.addAggregateInit(dest_ty, element_refs); |
| 22979 | 23322 | } |
| 22980 | 23323 | |
| ... | ... | @@ -23037,7 +23380,7 @@ fn coerceTupleToArray( |
| 23037 | 23380 | } |
| 23038 | 23381 | |
| 23039 | 23382 | if (runtime_src) |rs| { |
| 23040 | | try sema.requireRuntimeBlock(block, rs); |
| 23383 | try sema.requireRuntimeBlock(block, inst_src, rs); |
| 23041 | 23384 | return block.addAggregateInit(dest_ty, element_refs); |
| 23042 | 23385 | } |
| 23043 | 23386 | |
| ... | ... | @@ -23168,7 +23511,7 @@ fn coerceTupleToStruct( |
| 23168 | 23511 | } |
| 23169 | 23512 | |
| 23170 | 23513 | if (runtime_src) |rs| { |
| 23171 | | try sema.requireRuntimeBlock(block, rs); |
| 23514 | try sema.requireRuntimeBlock(block, inst_src, rs); |
| 23172 | 23515 | return block.addAggregateInit(struct_ty, field_refs); |
| 23173 | 23516 | } |
| 23174 | 23517 | |
| ... | ... | @@ -23282,7 +23625,7 @@ fn analyzeRef( |
| 23282 | 23625 | )); |
| 23283 | 23626 | } |
| 23284 | 23627 | |
| 23285 | | try sema.requireRuntimeBlock(block, src); |
| 23628 | try sema.requireRuntimeBlock(block, src, null); |
| 23286 | 23629 | const address_space = target_util.defaultAddressSpace(sema.mod.getTarget(), .local); |
| 23287 | 23630 | const ptr_type = try Type.ptr(sema.arena, sema.mod, .{ |
| 23288 | 23631 | .pointee_type = operand_ty, |
| ... | ... | @@ -23326,10 +23669,12 @@ fn analyzeLoad( |
| 23326 | 23669 | } |
| 23327 | 23670 | } |
| 23328 | 23671 | |
| 23329 | | const valid_rt = try sema.validateRunTimeType(block, src, elem_ty, false); |
| 23330 | | if (!valid_rt) return sema.failWithNeededComptime(block, src); |
| 23672 | if (block.is_comptime) { |
| 23673 | // TODO ideally this would tell why the block is comptime |
| 23674 | return sema.fail(block, ptr_src, "cannot load runtime value in comptime block", .{}); |
| 23675 | } |
| 23331 | 23676 | |
| 23332 | | try sema.requireRuntimeBlock(block, src); |
| 23677 | try sema.requireFunctionBlock(block, src); |
| 23333 | 23678 | return block.addTyOp(.load, elem_ty, ptr); |
| 23334 | 23679 | } |
| 23335 | 23680 | |
| ... | ... | @@ -23346,7 +23691,7 @@ fn analyzeSlicePtr( |
| 23346 | 23691 | if (val.isUndef()) return sema.addConstUndef(result_ty); |
| 23347 | 23692 | return sema.addConstant(result_ty, val.slicePtr()); |
| 23348 | 23693 | } |
| 23349 | | try sema.requireRuntimeBlock(block, slice_src); |
| 23694 | try sema.requireRuntimeBlock(block, slice_src, null); |
| 23350 | 23695 | return block.addTyOp(.slice_ptr, result_ty, slice); |
| 23351 | 23696 | } |
| 23352 | 23697 | |
| ... | ... | @@ -23362,7 +23707,7 @@ fn analyzeSliceLen( |
| 23362 | 23707 | } |
| 23363 | 23708 | return sema.addIntUnsigned(Type.usize, slice_val.sliceLen(sema.mod)); |
| 23364 | 23709 | } |
| 23365 | | try sema.requireRuntimeBlock(block, src); |
| 23710 | try sema.requireRuntimeBlock(block, src, null); |
| 23366 | 23711 | return block.addTyOp(.slice_len, Type.usize, slice_inst); |
| 23367 | 23712 | } |
| 23368 | 23713 | |
| ... | ... | @@ -23386,7 +23731,7 @@ fn analyzeIsNull( |
| 23386 | 23731 | return Air.Inst.Ref.bool_false; |
| 23387 | 23732 | } |
| 23388 | 23733 | } |
| 23389 | | try sema.requireRuntimeBlock(block, src); |
| 23734 | try sema.requireRuntimeBlock(block, src, null); |
| 23390 | 23735 | const air_tag: Air.Inst.Tag = if (invert_logic) .is_non_null else .is_null; |
| 23391 | 23736 | return block.addUnOp(air_tag, operand); |
| 23392 | 23737 | } |
| ... | ... | @@ -23476,7 +23821,7 @@ fn analyzeIsNonErr( |
| 23476 | 23821 | ) CompileError!Air.Inst.Ref { |
| 23477 | 23822 | const result = try sema.analyzeIsNonErrComptimeOnly(block, src, operand); |
| 23478 | 23823 | if (result == .none) { |
| 23479 | | try sema.requireRuntimeBlock(block, src); |
| 23824 | try sema.requireRuntimeBlock(block, src, null); |
| 23480 | 23825 | return block.addUnOp(.is_non_err, operand); |
| 23481 | 23826 | } else { |
| 23482 | 23827 | return result; |
| ... | ... | @@ -23661,7 +24006,7 @@ fn analyzeSlice( |
| 23661 | 24006 | const sentinel = s: { |
| 23662 | 24007 | if (sentinel_opt != .none) { |
| 23663 | 24008 | const casted = try sema.coerce(block, elem_ty, sentinel_opt, sentinel_src); |
| 23664 | | break :s try sema.resolveConstValue(block, sentinel_src, casted); |
| 24009 | break :s try sema.resolveConstValue(block, sentinel_src, casted, "slice sentinel must be comptime known"); |
| 23665 | 24010 | } |
| 23666 | 24011 | // If we are slicing to the end of something that is sentinel-terminated |
| 23667 | 24012 | // then the resulting slice type is also sentinel-terminated. |
| ... | ... | @@ -23738,7 +24083,14 @@ fn analyzeSlice( |
| 23738 | 24083 | .size = .Slice, |
| 23739 | 24084 | }); |
| 23740 | 24085 | |
| 23741 | | try sema.requireRuntimeBlock(block, src); |
| 24086 | const runtime_src = if ((try sema.resolveMaybeUndefVal(block, ptr_src, ptr_or_slice)) == null) |
| 24087 | ptr_src |
| 24088 | else if ((try sema.resolveMaybeUndefVal(block, src, start)) == null) |
| 24089 | start_src |
| 24090 | else |
| 24091 | end_src; |
| 24092 | |
| 24093 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 23742 | 24094 | if (block.wantSafety()) { |
| 23743 | 24095 | // requirement: slicing C ptr is non-null |
| 23744 | 24096 | if (ptr_ptr_child_ty.isCPtr()) { |
| ... | ... | @@ -23846,7 +24198,7 @@ fn cmpNumeric( |
| 23846 | 24198 | // a full resolution of their value, for example `@sizeOf(@Frame(function))` is known to |
| 23847 | 24199 | // always be nonzero, and we benefit from not forcing the full evaluation and stack frame layout |
| 23848 | 24200 | // of this function if we don't need to. |
| 23849 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 24201 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 23850 | 24202 | |
| 23851 | 24203 | // For floats, emit a float comparison instruction. |
| 23852 | 24204 | const lhs_is_float = switch (lhs_ty_tag) { |
| ... | ... | @@ -24034,7 +24386,7 @@ fn cmpVector( |
| 24034 | 24386 | } |
| 24035 | 24387 | }; |
| 24036 | 24388 | |
| 24037 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 24389 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 24038 | 24390 | const result_ty_inst = try sema.addType(result_ty); |
| 24039 | 24391 | return block.addCmpVector(lhs, rhs, op, result_ty_inst); |
| 24040 | 24392 | } |
| ... | ... | @@ -24050,7 +24402,7 @@ fn wrapOptional( |
| 24050 | 24402 | return sema.addConstant(dest_ty, try Value.Tag.opt_payload.create(sema.arena, val)); |
| 24051 | 24403 | } |
| 24052 | 24404 | |
| 24053 | | try sema.requireRuntimeBlock(block, inst_src); |
| 24405 | try sema.requireRuntimeBlock(block, inst_src, null); |
| 24054 | 24406 | return block.addTyOp(.wrap_optional, dest_ty, inst); |
| 24055 | 24407 | } |
| 24056 | 24408 | |
| ... | ... | @@ -24066,7 +24418,7 @@ fn wrapErrorUnionPayload( |
| 24066 | 24418 | if (try sema.resolveMaybeUndefVal(block, inst_src, coerced)) |val| { |
| 24067 | 24419 | return sema.addConstant(dest_ty, try Value.Tag.eu_payload.create(sema.arena, val)); |
| 24068 | 24420 | } |
| 24069 | | try sema.requireRuntimeBlock(block, inst_src); |
| 24421 | try sema.requireRuntimeBlock(block, inst_src, null); |
| 24070 | 24422 | try sema.queueFullTypeResolution(dest_payload_ty); |
| 24071 | 24423 | return block.addTyOp(.wrap_errunion_payload, dest_ty, coerced); |
| 24072 | 24424 | } |
| ... | ... | @@ -24122,7 +24474,7 @@ fn wrapErrorUnionSet( |
| 24122 | 24474 | return sema.addConstant(dest_ty, val); |
| 24123 | 24475 | } |
| 24124 | 24476 | |
| 24125 | | try sema.requireRuntimeBlock(block, inst_src); |
| 24477 | try sema.requireRuntimeBlock(block, inst_src, null); |
| 24126 | 24478 | const coerced = try sema.coerce(block, dest_err_set_ty, inst, inst_src); |
| 24127 | 24479 | return block.addTyOp(.wrap_errunion_err, dest_ty, coerced); |
| 24128 | 24480 | } |
| ... | ... | @@ -24140,7 +24492,7 @@ fn unionToTag( |
| 24140 | 24492 | if (try sema.resolveMaybeUndefVal(block, un_src, un)) |un_val| { |
| 24141 | 24493 | return sema.addConstant(enum_ty, un_val.unionTag()); |
| 24142 | 24494 | } |
| 24143 | | try sema.requireRuntimeBlock(block, un_src); |
| 24495 | try sema.requireRuntimeBlock(block, un_src, null); |
| 24144 | 24496 | return block.addTyOp(.get_union_tag, enum_ty, un); |
| 24145 | 24497 | } |
| 24146 | 24498 | |
| ... | ... | @@ -24889,20 +25241,6 @@ fn resolveStructFully( |
| 24889 | 25241 | struct_obj.status = .fully_resolved_wip; |
| 24890 | 25242 | for (struct_obj.fields.values()) |field| { |
| 24891 | 25243 | try sema.resolveTypeFully(block, src, field.ty); |
| 24892 | | |
| 24893 | | if (struct_obj.layout == .Extern and !(try sema.validateExternType(field.ty, .other))) { |
| 24894 | | const msg = msg: { |
| 24895 | | const msg = try sema.errMsg(block, src, "extern structs cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)}); |
| 24896 | | errdefer msg.destroy(sema.gpa); |
| 24897 | | |
| 24898 | | const src_decl = sema.mod.declPtr(block.src_decl); |
| 24899 | | try sema.explainWhyTypeIsNotExtern(block, src, msg, src.toSrcLoc(src_decl), field.ty, .other); |
| 24900 | | |
| 24901 | | try sema.addDeclaredHereNote(msg, field.ty); |
| 24902 | | break :msg msg; |
| 24903 | | }; |
| 24904 | | return sema.failWithOwnedErrorMsg(block, msg); |
| 24905 | | } |
| 24906 | 25244 | } |
| 24907 | 25245 | struct_obj.status = .fully_resolved; |
| 24908 | 25246 | } |
| ... | ... | @@ -24936,20 +25274,6 @@ fn resolveUnionFully( |
| 24936 | 25274 | union_obj.status = .fully_resolved_wip; |
| 24937 | 25275 | for (union_obj.fields.values()) |field| { |
| 24938 | 25276 | try sema.resolveTypeFully(block, src, field.ty); |
| 24939 | | |
| 24940 | | if (union_obj.layout == .Extern and !(try sema.validateExternType(field.ty, .union_field))) { |
| 24941 | | const msg = msg: { |
| 24942 | | const msg = try sema.errMsg(block, src, "extern unions cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)}); |
| 24943 | | errdefer msg.destroy(sema.gpa); |
| 24944 | | |
| 24945 | | const src_decl = sema.mod.declPtr(block.src_decl); |
| 24946 | | try sema.explainWhyTypeIsNotExtern(block, src, msg, src.toSrcLoc(src_decl), field.ty, .union_field); |
| 24947 | | |
| 24948 | | try sema.addDeclaredHereNote(msg, field.ty); |
| 24949 | | break :msg msg; |
| 24950 | | }; |
| 24951 | | return sema.failWithOwnedErrorMsg(block, msg); |
| 24952 | | } |
| 24953 | 25277 | } |
| 24954 | 25278 | union_obj.status = .fully_resolved; |
| 24955 | 25279 | } |
| ... | ... | @@ -25033,7 +25357,7 @@ fn resolveTypeFieldsUnion( |
| 25033 | 25357 | } |
| 25034 | 25358 | |
| 25035 | 25359 | union_obj.status = .field_types_wip; |
| 25036 | | try semaUnionFields(block, sema.mod, union_obj); |
| 25360 | try semaUnionFields(sema.mod, union_obj); |
| 25037 | 25361 | union_obj.status = .have_field_types; |
| 25038 | 25362 | } |
| 25039 | 25363 | |
| ... | ... | @@ -25287,6 +25611,33 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void |
| 25287 | 25611 | const field = &struct_obj.fields.values()[i]; |
| 25288 | 25612 | field.ty = try field_ty.copy(decl_arena_allocator); |
| 25289 | 25613 | |
| 25614 | if (struct_obj.layout == .Extern and !(try sema.validateExternType(field.ty, .other))) { |
| 25615 | const msg = msg: { |
| 25616 | const tree = try sema.getAstTree(&block_scope); |
| 25617 | const fields_src = enumFieldSrcLoc(decl, tree.*, struct_obj.node_offset, i); |
| 25618 | const msg = try sema.errMsg(&block_scope, fields_src, "extern structs cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)}); |
| 25619 | errdefer msg.destroy(sema.gpa); |
| 25620 | |
| 25621 | try sema.explainWhyTypeIsNotExtern(&block_scope, fields_src, msg, fields_src.toSrcLoc(decl), field.ty, .other); |
| 25622 | |
| 25623 | try sema.addDeclaredHereNote(msg, field.ty); |
| 25624 | break :msg msg; |
| 25625 | }; |
| 25626 | return sema.failWithOwnedErrorMsg(&block_scope, msg); |
| 25627 | } |
| 25628 | if (field_ty.zigTypeTag() == .Opaque) { |
| 25629 | const msg = msg: { |
| 25630 | const tree = try sema.getAstTree(&block_scope); |
| 25631 | const field_src = enumFieldSrcLoc(decl, tree.*, struct_obj.node_offset, i); |
| 25632 | const msg = try sema.errMsg(&block_scope, field_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{}); |
| 25633 | errdefer msg.destroy(sema.gpa); |
| 25634 | |
| 25635 | try sema.addDeclaredHereNote(msg, field_ty); |
| 25636 | break :msg msg; |
| 25637 | }; |
| 25638 | return sema.failWithOwnedErrorMsg(&block_scope, msg); |
| 25639 | } |
| 25640 | |
| 25290 | 25641 | if (zir_field.align_body_len > 0) { |
| 25291 | 25642 | const body = zir.extra[extra_index..][0..zir_field.align_body_len]; |
| 25292 | 25643 | extra_index += body.len; |
| ... | ... | @@ -25311,7 +25662,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void |
| 25311 | 25662 | const field = &struct_obj.fields.values()[i]; |
| 25312 | 25663 | const coerced = try sema.coerce(&block_scope, field.ty, init, src); |
| 25313 | 25664 | const default_val = (try sema.resolveMaybeUndefVal(&block_scope, src, coerced)) orelse |
| 25314 | | return sema.failWithNeededComptime(&block_scope, src); |
| 25665 | return sema.failWithNeededComptime(&block_scope, src, "struct field default value must be comptime known"); |
| 25315 | 25666 | field.default_val = try default_val.copy(decl_arena_allocator); |
| 25316 | 25667 | } |
| 25317 | 25668 | } |
| ... | ... | @@ -25320,7 +25671,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void |
| 25320 | 25671 | struct_obj.have_field_inits = true; |
| 25321 | 25672 | } |
| 25322 | 25673 | |
| 25323 | | fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 25674 | fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 25324 | 25675 | const tracy = trace(@src()); |
| 25325 | 25676 | defer tracy.end(); |
| 25326 | 25677 | |
| ... | ... | @@ -25425,10 +25776,14 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil |
| 25425 | 25776 | var enum_value_map: ?*Module.EnumNumbered.ValueMap = null; |
| 25426 | 25777 | var tag_ty_field_names: ?Module.EnumFull.NameMap = null; |
| 25427 | 25778 | if (tag_type_ref != .none) { |
| 25428 | | const provided_ty = try sema.resolveType(&block_scope, src, tag_type_ref); |
| 25779 | const tag_ty_src: LazySrcLoc = .{ .node_offset_container_tag = src.node_offset.x }; |
| 25780 | const provided_ty = try sema.resolveType(&block_scope, tag_ty_src, tag_type_ref); |
| 25429 | 25781 | if (small.auto_enum_tag) { |
| 25430 | 25782 | // The provided type is an integer type and we must construct the enum tag type here. |
| 25431 | 25783 | int_tag_ty = provided_ty; |
| 25784 | if (int_tag_ty.zigTypeTag() != .Int and int_tag_ty.zigTypeTag() != .ComptimeInt) { |
| 25785 | return sema.fail(&block_scope, tag_ty_src, "expected integer tag type, found '{}'", .{int_tag_ty.fmt(sema.mod)}); |
| 25786 | } |
| 25432 | 25787 | union_obj.tag_ty = try sema.generateUnionTagTypeNumbered(&block_scope, fields_len, provided_ty, union_obj); |
| 25433 | 25788 | const enum_obj = union_obj.tag_ty.castTag(.enum_numbered).?.data; |
| 25434 | 25789 | enum_field_names = &enum_obj.fields; |
| ... | ... | @@ -25437,8 +25792,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil |
| 25437 | 25792 | // The provided type is the enum tag type. |
| 25438 | 25793 | union_obj.tag_ty = try provided_ty.copy(decl_arena_allocator); |
| 25439 | 25794 | if (union_obj.tag_ty.zigTypeTag() != .Enum) { |
| 25440 | | const tag_ty_src = src; // TODO better source location |
| 25441 | | return sema.fail(block, tag_ty_src, "expected enum tag type, found '{}'", .{union_obj.tag_ty.fmt(sema.mod)}); |
| 25795 | return sema.fail(&block_scope, tag_ty_src, "expected enum tag type, found '{}'", .{union_obj.tag_ty.fmt(sema.mod)}); |
| 25442 | 25796 | } |
| 25443 | 25797 | // The fields of the union must match the enum exactly. |
| 25444 | 25798 | // Store a copy of the enum field names so we can check for |
| ... | ... | @@ -25504,7 +25858,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil |
| 25504 | 25858 | if (tag_ref != .none) { |
| 25505 | 25859 | const tag_src = src; // TODO better source location |
| 25506 | 25860 | const coerced = try sema.coerce(&block_scope, int_tag_ty, tag_ref, tag_src); |
| 25507 | | const val = try sema.resolveConstValue(&block_scope, tag_src, coerced); |
| 25861 | const val = try sema.resolveConstValue(&block_scope, tag_src, coerced, "enum tag value must be comptime known"); |
| 25508 | 25862 | last_tag_val = val; |
| 25509 | 25863 | |
| 25510 | 25864 | // This puts the memory into the union arena, not the enum arena, but |
| ... | ... | @@ -25516,7 +25870,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil |
| 25516 | 25870 | }); |
| 25517 | 25871 | } else { |
| 25518 | 25872 | const val = if (last_tag_val) |val| |
| 25519 | | try sema.intAdd(block, src, val, Value.one, int_tag_ty) |
| 25873 | try sema.intAdd(&block_scope, src, val, Value.one, int_tag_ty) |
| 25520 | 25874 | else |
| 25521 | 25875 | Value.zero; |
| 25522 | 25876 | last_tag_val = val; |
| ... | ... | @@ -25570,15 +25924,44 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil |
| 25570 | 25924 | const enum_has_field = names.orderedRemove(field_name); |
| 25571 | 25925 | if (!enum_has_field) { |
| 25572 | 25926 | const msg = msg: { |
| 25573 | | const msg = try sema.errMsg(block, src, "enum '{}' has no field named '{s}'", .{ union_obj.tag_ty.fmt(sema.mod), field_name }); |
| 25927 | const tree = try sema.getAstTree(&block_scope); |
| 25928 | const field_src = enumFieldSrcLoc(decl, tree.*, union_obj.node_offset, field_i); |
| 25929 | const msg = try sema.errMsg(&block_scope, field_src, "enum '{}' has no field named '{s}'", .{ union_obj.tag_ty.fmt(sema.mod), field_name }); |
| 25574 | 25930 | errdefer msg.destroy(sema.gpa); |
| 25575 | 25931 | try sema.addDeclaredHereNote(msg, union_obj.tag_ty); |
| 25576 | 25932 | break :msg msg; |
| 25577 | 25933 | }; |
| 25578 | | return sema.failWithOwnedErrorMsg(block, msg); |
| 25934 | return sema.failWithOwnedErrorMsg(&block_scope, msg); |
| 25579 | 25935 | } |
| 25580 | 25936 | } |
| 25581 | 25937 | |
| 25938 | if (union_obj.layout == .Extern and !(try sema.validateExternType(field_ty, .union_field))) { |
| 25939 | const msg = msg: { |
| 25940 | const tree = try sema.getAstTree(&block_scope); |
| 25941 | const field_src = enumFieldSrcLoc(decl, tree.*, union_obj.node_offset, field_i); |
| 25942 | const msg = try sema.errMsg(&block_scope, field_src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)}); |
| 25943 | errdefer msg.destroy(sema.gpa); |
| 25944 | |
| 25945 | try sema.explainWhyTypeIsNotExtern(&block_scope, field_src, msg, field_src.toSrcLoc(decl), field_ty, .union_field); |
| 25946 | |
| 25947 | try sema.addDeclaredHereNote(msg, field_ty); |
| 25948 | break :msg msg; |
| 25949 | }; |
| 25950 | return sema.failWithOwnedErrorMsg(&block_scope, msg); |
| 25951 | } |
| 25952 | if (field_ty.zigTypeTag() == .Opaque) { |
| 25953 | const msg = msg: { |
| 25954 | const tree = try sema.getAstTree(&block_scope); |
| 25955 | const field_src = enumFieldSrcLoc(decl, tree.*, union_obj.node_offset, field_i); |
| 25956 | const msg = try sema.errMsg(&block_scope, field_src, "opaque types have unknown size and therefore cannot be directly embedded in unions", .{}); |
| 25957 | errdefer msg.destroy(sema.gpa); |
| 25958 | |
| 25959 | try sema.addDeclaredHereNote(msg, field_ty); |
| 25960 | break :msg msg; |
| 25961 | }; |
| 25962 | return sema.failWithOwnedErrorMsg(&block_scope, msg); |
| 25963 | } |
| 25964 | |
| 25582 | 25965 | gop.value_ptr.* = .{ |
| 25583 | 25966 | .ty = try field_ty.copy(decl_arena_allocator), |
| 25584 | 25967 | .abi_align = 0, |
| ... | ... | @@ -25597,18 +25980,18 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil |
| 25597 | 25980 | if (tag_ty_field_names) |names| { |
| 25598 | 25981 | if (names.count() > 0) { |
| 25599 | 25982 | const msg = msg: { |
| 25600 | | const msg = try sema.errMsg(block, src, "enum field(s) missing in union", .{}); |
| 25983 | const msg = try sema.errMsg(&block_scope, src, "enum field(s) missing in union", .{}); |
| 25601 | 25984 | errdefer msg.destroy(sema.gpa); |
| 25602 | 25985 | |
| 25603 | 25986 | const enum_ty = union_obj.tag_ty; |
| 25604 | 25987 | for (names.keys()) |field_name| { |
| 25605 | 25988 | const field_index = enum_ty.enumFieldIndex(field_name).?; |
| 25606 | | try sema.addFieldErrNote(block, enum_ty, field_index, msg, "field '{s}' missing, declared here", .{field_name}); |
| 25989 | try sema.addFieldErrNote(&block_scope, enum_ty, field_index, msg, "field '{s}' missing, declared here", .{field_name}); |
| 25607 | 25990 | } |
| 25608 | 25991 | try sema.addDeclaredHereNote(msg, union_obj.tag_ty); |
| 25609 | 25992 | break :msg msg; |
| 25610 | 25993 | }; |
| 25611 | | return sema.failWithOwnedErrorMsg(block, msg); |
| 25994 | return sema.failWithOwnedErrorMsg(&block_scope, msg); |
| 25612 | 25995 | } |
| 25613 | 25996 | } |
| 25614 | 25997 | } |
| ... | ... | @@ -26247,7 +26630,7 @@ pub fn analyzeAddrspace( |
| 26247 | 26630 | zir_ref: Zir.Inst.Ref, |
| 26248 | 26631 | ctx: AddressSpaceContext, |
| 26249 | 26632 | ) !std.builtin.AddressSpace { |
| 26250 | | const addrspace_tv = try sema.resolveInstConst(block, src, zir_ref); |
| 26633 | const addrspace_tv = try sema.resolveInstConst(block, src, zir_ref, "addresspace must be comptime known"); |
| 26251 | 26634 | const address_space = addrspace_tv.val.toEnum(std.builtin.AddressSpace); |
| 26252 | 26635 | const target = sema.mod.getTarget(); |
| 26253 | 26636 | const arch = target.cpu.arch; |