| author | |
| committer | |
| log | 356a865b871db458149f70bc103a3971780d6962 |
| tree | c4e06c84ce3735b48add6e89c69cf6cc3e84da1c |
| parent | 602af1b88f150f8b09d980520620ab289c425075 |
Not implemented yet is enhancements to coerceInMemory to account for
noalias parameters.
Related to #11498.6 files changed, 108 insertions(+), 23 deletions(-)
src/AstGen.zig+33-10| ... | ... | @@ -1155,14 +1155,20 @@ fn fnProtoExpr( |
| 1155 | 1155 | |
| 1156 | 1156 | const block_inst = try gz.makeBlockInst(.block_inline, node); |
| 1157 | 1157 | |
| 1158 | var noalias_bits: u32 = 0; | |
| 1158 | 1159 | const is_var_args = is_var_args: { |
| 1159 | 1160 | var param_type_i: usize = 0; |
| 1160 | 1161 | var it = fn_proto.iterate(tree); |
| 1161 | 1162 | while (it.next()) |param| : (param_type_i += 1) { |
| 1162 | const is_comptime = if (param.comptime_noalias) |token| | |
| 1163 | token_tags[token] == .keyword_comptime | |
| 1164 | else | |
| 1165 | false; | |
| 1163 | const is_comptime = if (param.comptime_noalias) |token| switch (token_tags[token]) { | |
| 1164 | .keyword_noalias => is_comptime: { | |
| 1165 | noalias_bits |= @as(u32, 1) << (std.math.cast(u5, param_type_i) orelse | |
| 1166 | return astgen.failTok(token, "this compiler implementation only supports 'noalias' on the first 32 parameters", .{})); | |
| 1167 | break :is_comptime false; | |
| 1168 | }, | |
| 1169 | .keyword_comptime => true, | |
| 1170 | else => false, | |
| 1171 | } else false; | |
| 1166 | 1172 | |
| 1167 | 1173 | const is_anytype = if (param.anytype_ellipsis3) |token| blk: { |
| 1168 | 1174 | switch (token_tags[token]) { |
| ... | ... | @@ -1255,6 +1261,7 @@ fn fnProtoExpr( |
| 1255 | 1261 | .is_inferred_error = false, |
| 1256 | 1262 | .is_test = false, |
| 1257 | 1263 | .is_extern = false, |
| 1264 | .noalias_bits = noalias_bits, | |
| 1258 | 1265 | }); |
| 1259 | 1266 | |
| 1260 | 1267 | _ = try block_scope.addBreak(.break_inline, block_inst, result); |
| ... | ... | @@ -3381,15 +3388,21 @@ fn fnDecl( |
| 3381 | 3388 | // align, linksection, and addrspace is passed in the func instruction in this case. |
| 3382 | 3389 | wip_members.nextDecl(is_pub, is_export, false, false); |
| 3383 | 3390 | |
| 3391 | var noalias_bits: u32 = 0; | |
| 3384 | 3392 | var params_scope = &fn_gz.base; |
| 3385 | 3393 | const is_var_args = is_var_args: { |
| 3386 | 3394 | var param_type_i: usize = 0; |
| 3387 | 3395 | var it = fn_proto.iterate(tree); |
| 3388 | 3396 | while (it.next()) |param| : (param_type_i += 1) { |
| 3389 | const is_comptime = if (param.comptime_noalias) |token| | |
| 3390 | token_tags[token] == .keyword_comptime | |
| 3391 | else | |
| 3392 | false; | |
| 3397 | const is_comptime = if (param.comptime_noalias) |token| switch (token_tags[token]) { | |
| 3398 | .keyword_noalias => is_comptime: { | |
| 3399 | noalias_bits |= @as(u32, 1) << (std.math.cast(u5, param_type_i) orelse | |
| 3400 | return astgen.failTok(token, "this compiler implementation only supports 'noalias' on the first 32 parameters", .{})); | |
| 3401 | break :is_comptime false; | |
| 3402 | }, | |
| 3403 | .keyword_comptime => true, | |
| 3404 | else => false, | |
| 3405 | } else false; | |
| 3393 | 3406 | |
| 3394 | 3407 | const is_anytype = if (param.anytype_ellipsis3) |token| blk: { |
| 3395 | 3408 | switch (token_tags[token]) { |
| ... | ... | @@ -3576,6 +3589,7 @@ fn fnDecl( |
| 3576 | 3589 | .is_inferred_error = false, |
| 3577 | 3590 | .is_test = false, |
| 3578 | 3591 | .is_extern = true, |
| 3592 | .noalias_bits = noalias_bits, | |
| 3579 | 3593 | }); |
| 3580 | 3594 | } else func: { |
| 3581 | 3595 | if (is_var_args) { |
| ... | ... | @@ -3623,6 +3637,7 @@ fn fnDecl( |
| 3623 | 3637 | .is_inferred_error = is_inferred_error, |
| 3624 | 3638 | .is_test = false, |
| 3625 | 3639 | .is_extern = false, |
| 3640 | .noalias_bits = noalias_bits, | |
| 3626 | 3641 | }); |
| 3627 | 3642 | }; |
| 3628 | 3643 | |
| ... | ... | @@ -4057,6 +4072,7 @@ fn testDecl( |
| 4057 | 4072 | .is_inferred_error = true, |
| 4058 | 4073 | .is_test = true, |
| 4059 | 4074 | .is_extern = false, |
| 4075 | .noalias_bits = 0, | |
| 4060 | 4076 | }); |
| 4061 | 4077 | |
| 4062 | 4078 | _ = try decl_block.addBreak(.break_inline, block_inst, func_inst); |
| ... | ... | @@ -10024,6 +10040,7 @@ const GenZir = struct { |
| 10024 | 10040 | ret_ref: Zir.Inst.Ref, |
| 10025 | 10041 | |
| 10026 | 10042 | lib_name: u32, |
| 10043 | noalias_bits: u32, | |
| 10027 | 10044 | is_var_args: bool, |
| 10028 | 10045 | is_inferred_error: bool, |
| 10029 | 10046 | is_test: bool, |
| ... | ... | @@ -10071,7 +10088,7 @@ const GenZir = struct { |
| 10071 | 10088 | if (args.cc_ref != .none or args.lib_name != 0 or |
| 10072 | 10089 | args.is_var_args or args.is_test or args.is_extern or |
| 10073 | 10090 | args.align_ref != .none or args.section_ref != .none or |
| 10074 | args.addrspace_ref != .none) | |
| 10091 | args.addrspace_ref != .none or args.noalias_bits != 0) | |
| 10075 | 10092 | { |
| 10076 | 10093 | var align_body: []Zir.Inst.Index = &.{}; |
| 10077 | 10094 | var addrspace_body: []Zir.Inst.Index = &.{}; |
| ... | ... | @@ -10093,7 +10110,8 @@ const GenZir = struct { |
| 10093 | 10110 | fancyFnExprExtraLen(cc_body, args.cc_ref) + |
| 10094 | 10111 | fancyFnExprExtraLen(ret_body, ret_ref) + |
| 10095 | 10112 | body.len + src_locs.len + |
| 10096 | @boolToInt(args.lib_name != 0), | |
| 10113 | @boolToInt(args.lib_name != 0) + | |
| 10114 | @boolToInt(args.noalias_bits != 0), | |
| 10097 | 10115 | ); |
| 10098 | 10116 | const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.FuncFancy{ |
| 10099 | 10117 | .param_block = args.param_block, |
| ... | ... | @@ -10104,6 +10122,7 @@ const GenZir = struct { |
| 10104 | 10122 | .is_test = args.is_test, |
| 10105 | 10123 | .is_extern = args.is_extern, |
| 10106 | 10124 | .has_lib_name = args.lib_name != 0, |
| 10125 | .has_any_noalias = args.noalias_bits != 0, | |
| 10107 | 10126 | |
| 10108 | 10127 | .has_align_ref = args.align_ref != .none, |
| 10109 | 10128 | .has_addrspace_ref = args.addrspace_ref != .none, |
| ... | ... | @@ -10159,6 +10178,10 @@ const GenZir = struct { |
| 10159 | 10178 | astgen.extra.appendAssumeCapacity(@enumToInt(ret_ref)); |
| 10160 | 10179 | } |
| 10161 | 10180 | |
| 10181 | if (args.noalias_bits != 0) { | |
| 10182 | astgen.extra.appendAssumeCapacity(args.noalias_bits); | |
| 10183 | } | |
| 10184 | ||
| 10162 | 10185 | astgen.extra.appendSliceAssumeCapacity(body); |
| 10163 | 10186 | astgen.extra.appendSliceAssumeCapacity(src_locs); |
| 10164 | 10187 |
src/Sema.zig+12-5| ... | ... | @@ -6565,12 +6565,10 @@ fn zirFunc( |
| 6565 | 6565 | has_body, |
| 6566 | 6566 | src_locs, |
| 6567 | 6567 | null, |
| 6568 | 0, | |
| 6568 | 6569 | ); |
| 6569 | 6570 | } |
| 6570 | 6571 | |
| 6571 | // TODO this function and its callsites along with funcCommon need to be reworked | |
| 6572 | // to handle when callconv, align, linksection, addrspace depend on comptime values | |
| 6573 | // (thus triggering error.GenericPoison) | |
| 6574 | 6572 | fn resolveGenericBody( |
| 6575 | 6573 | sema: *Sema, |
| 6576 | 6574 | block: *Block, |
| ... | ... | @@ -6696,6 +6694,7 @@ fn funcCommon( |
| 6696 | 6694 | has_body: bool, |
| 6697 | 6695 | src_locs: Zir.Inst.Func.SrcLocs, |
| 6698 | 6696 | opt_lib_name: ?[]const u8, |
| 6697 | noalias_bits: u32, | |
| 6699 | 6698 | ) CompileError!Air.Inst.Ref { |
| 6700 | 6699 | const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = src_node_offset }; |
| 6701 | 6700 | |
| ... | ... | @@ -6807,6 +6806,7 @@ fn funcCommon( |
| 6807 | 6806 | .addrspace_is_generic = address_space == null, |
| 6808 | 6807 | .is_var_args = var_args, |
| 6809 | 6808 | .is_generic = is_generic, |
| 6809 | .noalias_bits = noalias_bits, | |
| 6810 | 6810 | }); |
| 6811 | 6811 | }; |
| 6812 | 6812 | |
| ... | ... | @@ -9626,7 +9626,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 9626 | 9626 | const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; |
| 9627 | 9627 | const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; |
| 9628 | 9628 | |
| 9629 | // In `**` rhs has to be comptime-known, but lhs can be runtime-known | |
| 9629 | // In `**` rhs must be comptime-known, but lhs can be runtime-known | |
| 9630 | 9630 | const factor = try sema.resolveInt(block, rhs_src, extra.rhs, Type.usize); |
| 9631 | 9631 | |
| 9632 | 9632 | if (lhs_ty.isTuple()) { |
| ... | ... | @@ -11916,7 +11916,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 11916 | 11916 | |
| 11917 | 11917 | try sema.queueFullTypeResolution(try error_field_ty.copy(sema.arena)); |
| 11918 | 11918 | |
| 11919 | // If the error set is inferred it has to be resolved at this point | |
| 11919 | // If the error set is inferred it must be resolved at this point | |
| 11920 | 11920 | try sema.resolveInferredErrorSetTy(block, src, ty); |
| 11921 | 11921 | |
| 11922 | 11922 | // Build our list of Error values |
| ... | ... | @@ -16970,6 +16970,12 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 16970 | 16970 | break :blk ty; |
| 16971 | 16971 | } else Type.void; |
| 16972 | 16972 | |
| 16973 | const noalias_bits: u32 = if (extra.data.bits.has_any_noalias) blk: { | |
| 16974 | const x = sema.code.extra[extra_index]; | |
| 16975 | extra_index += 1; | |
| 16976 | break :blk x; | |
| 16977 | } else 0; | |
| 16978 | ||
| 16973 | 16979 | var src_locs: Zir.Inst.Func.SrcLocs = undefined; |
| 16974 | 16980 | const has_body = extra.data.body_len != 0; |
| 16975 | 16981 | if (has_body) { |
| ... | ... | @@ -16996,6 +17002,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 16996 | 17002 | has_body, |
| 16997 | 17003 | src_locs, |
| 16998 | 17004 | lib_name, |
| 17005 | noalias_bits, | |
| 16999 | 17006 | ); |
| 17000 | 17007 | } |
| 17001 | 17008 |
src/Zir.zig+11-3| ... | ... | @@ -2670,8 +2670,10 @@ pub const Inst = struct { |
| 2670 | 2670 | /// 14. ret_ty_body_len: u32 |
| 2671 | 2671 | /// 15. ret_ty_body: u32 // for each ret_ty_body_len |
| 2672 | 2672 | /// } |
| 2673 | /// 16. body: Index // for each body_len | |
| 2674 | /// 17. src_locs: Func.SrcLocs // if body_len != 0 | |
| 2673 | /// 16. noalias_bits: u32 // if has_any_noalias | |
| 2674 | /// - each bit starting with LSB corresponds to parameter indexes | |
| 2675 | /// 17. body: Index // for each body_len | |
| 2676 | /// 18. src_locs: Func.SrcLocs // if body_len != 0 | |
| 2675 | 2677 | pub const FuncFancy = struct { |
| 2676 | 2678 | /// Points to the block that contains the param instructions for this function. |
| 2677 | 2679 | param_block: Index, |
| ... | ... | @@ -2699,7 +2701,8 @@ pub const Inst = struct { |
| 2699 | 2701 | has_ret_ty_ref: bool, |
| 2700 | 2702 | has_ret_ty_body: bool, |
| 2701 | 2703 | has_lib_name: bool, |
| 2702 | _: u17 = undefined, | |
| 2704 | has_any_noalias: bool, | |
| 2705 | _: u16 = undefined, | |
| 2703 | 2706 | }; |
| 2704 | 2707 | }; |
| 2705 | 2708 | |
| ... | ... | @@ -3699,6 +3702,8 @@ fn findDeclsInner( |
| 3699 | 3702 | extra_index += 1; |
| 3700 | 3703 | } |
| 3701 | 3704 | |
| 3705 | extra_index += @boolToInt(extra.data.bits.has_any_noalias); | |
| 3706 | ||
| 3702 | 3707 | const body = zir.extra[extra_index..][0..extra.data.body_len]; |
| 3703 | 3708 | return zir.findDeclsBody(list, body); |
| 3704 | 3709 | }, |
| ... | ... | @@ -3906,6 +3911,9 @@ pub fn getFnInfo(zir: Zir, fn_inst: Inst.Index) FnInfo { |
| 3906 | 3911 | ret_ty_ref = @intToEnum(Inst.Ref, zir.extra[extra_index]); |
| 3907 | 3912 | extra_index += 1; |
| 3908 | 3913 | } |
| 3914 | ||
| 3915 | extra_index += @boolToInt(extra.data.bits.has_any_noalias); | |
| 3916 | ||
| 3909 | 3917 | const body = zir.extra[extra_index..][0..extra.data.body_len]; |
| 3910 | 3918 | extra_index += body.len; |
| 3911 | 3919 | break :blk .{ |
src/codegen/llvm.zig+5-1| ... | ... | @@ -725,8 +725,12 @@ pub const Object = struct { |
| 725 | 725 | try args.append(param); |
| 726 | 726 | |
| 727 | 727 | if (param_ty.isPtrAtRuntime()) { |
| 728 | // TODO noalias attribute | |
| 729 | 728 | const ptr_info = param_ty.ptrInfo().data; |
| 729 | if (math.cast(u5, it.zig_index - 1)) |i| { | |
| 730 | if (@truncate(u1, fn_info.noalias_bits >> i) != 0) { | |
| 731 | dg.addArgAttr(llvm_func, llvm_arg_i, "noalias"); | |
| 732 | } | |
| 733 | } | |
| 730 | 734 | if (!param_ty.isPtrLikeOptional() and !ptr_info.@"allowzero") { |
| 731 | 735 | dg.addArgAttr(llvm_func, llvm_arg_i, "nonnull"); |
| 732 | 736 | } |
src/print_zir.zig+13| ... | ... | @@ -1961,6 +1961,7 @@ const Writer = struct { |
| 1961 | 1961 | body, |
| 1962 | 1962 | src, |
| 1963 | 1963 | src_locs, |
| 1964 | 0, | |
| 1964 | 1965 | ); |
| 1965 | 1966 | } |
| 1966 | 1967 | |
| ... | ... | @@ -2034,6 +2035,12 @@ const Writer = struct { |
| 2034 | 2035 | extra_index += 1; |
| 2035 | 2036 | } |
| 2036 | 2037 | |
| 2038 | const noalias_bits: u32 = if (extra.data.bits.has_any_noalias) blk: { | |
| 2039 | const x = self.code.extra[extra_index]; | |
| 2040 | extra_index += 1; | |
| 2041 | break :blk x; | |
| 2042 | } else 0; | |
| 2043 | ||
| 2037 | 2044 | const body = self.code.extra[extra_index..][0..extra.data.body_len]; |
| 2038 | 2045 | extra_index += body.len; |
| 2039 | 2046 | |
| ... | ... | @@ -2059,6 +2066,7 @@ const Writer = struct { |
| 2059 | 2066 | body, |
| 2060 | 2067 | src, |
| 2061 | 2068 | src_locs, |
| 2069 | noalias_bits, | |
| 2062 | 2070 | ); |
| 2063 | 2071 | } |
| 2064 | 2072 | |
| ... | ... | @@ -2216,6 +2224,7 @@ const Writer = struct { |
| 2216 | 2224 | body: []const Zir.Inst.Index, |
| 2217 | 2225 | src: LazySrcLoc, |
| 2218 | 2226 | src_locs: Zir.Inst.Func.SrcLocs, |
| 2227 | noalias_bits: u32, | |
| 2219 | 2228 | ) !void { |
| 2220 | 2229 | try self.writeOptionalInstRefOrBody(stream, "align=", align_ref, align_body); |
| 2221 | 2230 | try self.writeOptionalInstRefOrBody(stream, "addrspace=", addrspace_ref, addrspace_body); |
| ... | ... | @@ -2226,6 +2235,10 @@ const Writer = struct { |
| 2226 | 2235 | try self.writeFlag(stream, "extern, ", is_extern); |
| 2227 | 2236 | try self.writeFlag(stream, "inferror, ", inferred_error_set); |
| 2228 | 2237 | |
| 2238 | if (noalias_bits != 0) { | |
| 2239 | try stream.print("noalias=0b{b}, ", .{noalias_bits}); | |
| 2240 | } | |
| 2241 | ||
| 2229 | 2242 | try stream.writeAll("body="); |
| 2230 | 2243 | try self.writeBracedBody(stream, body); |
| 2231 | 2244 | try stream.writeAll(") "); |
src/type.zig+34-4| ... | ... | @@ -646,6 +646,9 @@ pub const Type = extern union { |
| 646 | 646 | if (a_info.is_generic != b_info.is_generic) |
| 647 | 647 | return false; |
| 648 | 648 | |
| 649 | if (a_info.noalias_bits != b_info.noalias_bits) | |
| 650 | return false; | |
| 651 | ||
| 649 | 652 | if (!a_info.cc_is_generic and a_info.cc != b_info.cc) |
| 650 | 653 | return false; |
| 651 | 654 | |
| ... | ... | @@ -1047,6 +1050,7 @@ pub const Type = extern union { |
| 1047 | 1050 | } |
| 1048 | 1051 | std.hash.autoHash(hasher, fn_info.is_var_args); |
| 1049 | 1052 | std.hash.autoHash(hasher, fn_info.is_generic); |
| 1053 | std.hash.autoHash(hasher, fn_info.noalias_bits); | |
| 1050 | 1054 | |
| 1051 | 1055 | std.hash.autoHash(hasher, fn_info.param_types.len); |
| 1052 | 1056 | for (fn_info.param_types) |param_ty, i| { |
| ... | ... | @@ -1424,6 +1428,11 @@ pub const Type = extern union { |
| 1424 | 1428 | .is_var_args = payload.is_var_args, |
| 1425 | 1429 | .is_generic = payload.is_generic, |
| 1426 | 1430 | .comptime_params = comptime_params.ptr, |
| 1431 | .align_is_generic = payload.align_is_generic, | |
| 1432 | .cc_is_generic = payload.cc_is_generic, | |
| 1433 | .section_is_generic = payload.section_is_generic, | |
| 1434 | .addrspace_is_generic = payload.addrspace_is_generic, | |
| 1435 | .noalias_bits = payload.noalias_bits, | |
| 1427 | 1436 | }); |
| 1428 | 1437 | }, |
| 1429 | 1438 | .pointer => { |
| ... | ... | @@ -4738,6 +4747,11 @@ pub const Type = extern union { |
| 4738 | 4747 | .alignment = 0, |
| 4739 | 4748 | .is_var_args = false, |
| 4740 | 4749 | .is_generic = false, |
| 4750 | .align_is_generic = false, | |
| 4751 | .cc_is_generic = false, | |
| 4752 | .section_is_generic = false, | |
| 4753 | .addrspace_is_generic = false, | |
| 4754 | .noalias_bits = 0, | |
| 4741 | 4755 | }, |
| 4742 | 4756 | .fn_void_no_args => .{ |
| 4743 | 4757 | .param_types = &.{}, |
| ... | ... | @@ -4747,6 +4761,11 @@ pub const Type = extern union { |
| 4747 | 4761 | .alignment = 0, |
| 4748 | 4762 | .is_var_args = false, |
| 4749 | 4763 | .is_generic = false, |
| 4764 | .align_is_generic = false, | |
| 4765 | .cc_is_generic = false, | |
| 4766 | .section_is_generic = false, | |
| 4767 | .addrspace_is_generic = false, | |
| 4768 | .noalias_bits = 0, | |
| 4750 | 4769 | }, |
| 4751 | 4770 | .fn_naked_noreturn_no_args => .{ |
| 4752 | 4771 | .param_types = &.{}, |
| ... | ... | @@ -4756,6 +4775,11 @@ pub const Type = extern union { |
| 4756 | 4775 | .alignment = 0, |
| 4757 | 4776 | .is_var_args = false, |
| 4758 | 4777 | .is_generic = false, |
| 4778 | .align_is_generic = false, | |
| 4779 | .cc_is_generic = false, | |
| 4780 | .section_is_generic = false, | |
| 4781 | .addrspace_is_generic = false, | |
| 4782 | .noalias_bits = 0, | |
| 4759 | 4783 | }, |
| 4760 | 4784 | .fn_ccc_void_no_args => .{ |
| 4761 | 4785 | .param_types = &.{}, |
| ... | ... | @@ -4765,6 +4789,11 @@ pub const Type = extern union { |
| 4765 | 4789 | .alignment = 0, |
| 4766 | 4790 | .is_var_args = false, |
| 4767 | 4791 | .is_generic = false, |
| 4792 | .align_is_generic = false, | |
| 4793 | .cc_is_generic = false, | |
| 4794 | .section_is_generic = false, | |
| 4795 | .addrspace_is_generic = false, | |
| 4796 | .noalias_bits = 0, | |
| 4768 | 4797 | }, |
| 4769 | 4798 | .function => ty.castTag(.function).?.data, |
| 4770 | 4799 | |
| ... | ... | @@ -6123,13 +6152,14 @@ pub const Type = extern union { |
| 6123 | 6152 | return_type: Type, |
| 6124 | 6153 | /// If zero use default target function code alignment. |
| 6125 | 6154 | alignment: u32, |
| 6155 | noalias_bits: u32, | |
| 6126 | 6156 | cc: std.builtin.CallingConvention, |
| 6127 | 6157 | is_var_args: bool, |
| 6128 | 6158 | is_generic: bool, |
| 6129 | align_is_generic: bool = false, | |
| 6130 | cc_is_generic: bool = false, | |
| 6131 | section_is_generic: bool = false, | |
| 6132 | addrspace_is_generic: bool = false, | |
| 6159 | align_is_generic: bool, | |
| 6160 | cc_is_generic: bool, | |
| 6161 | section_is_generic: bool, | |
| 6162 | addrspace_is_generic: bool, | |
| 6133 | 6163 | |
| 6134 | 6164 | pub fn paramIsComptime(self: @This(), i: usize) bool { |
| 6135 | 6165 | assert(i < self.param_types.len); |