diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-08-01 22:04:18 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-08-01 22:04:18 -0700 |
| commit | dae4c18aa7999a866b6b145ed3c88cb6c06852be (patch) | |
| tree | 6aa41102b19c8e0af04bf1dd8af5158c4cc8b3a5 /src/Sema.zig | |
| parent | d5f173d28f2991e05dad399ed4d688297e0a5ca7 (diff) | |
| download | zig-dae4c18aa7999a866b6b145ed3c88cb6c06852be.tar.gz zig-dae4c18aa7999a866b6b145ed3c88cb6c06852be.zip | |
stage2: ZIR encodes comptime parameters
`func_extended` ZIR instructions now have a one of the unused flags used
as a `has_comptime_bits` boolean. When set, it means 1 or more
parameters are `comptime`. In this case, there is a u32 per every 32
parameters (usually just 1 u32) with each bit indicating whether the
corresponding parameter is `comptime`.
Sema uses this information to correctly mark generic functions as
generic. There is now a TODO compile error in place in case a generic
function call happens. A future commit will do the generic function call
implementation.
Diffstat (limited to 'src/Sema.zig')
| -rw-r--r-- | src/Sema.zig | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 6b281f8569..753ef8fb9c 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -104,6 +104,9 @@ pub fn analyzeFnBody( extra_index += @boolToInt(small.has_lib_name); extra_index += @boolToInt(small.has_cc); extra_index += @boolToInt(small.has_align); + if (small.has_comptime_bits) { + extra_index += (extra.data.param_types_len + 31) / 32; + } extra_index += extra.data.param_types_len; const body = sema.code.extra[extra_index..][0..extra.data.body_len]; break :blk body; @@ -2533,6 +2536,9 @@ fn analyzeCall( break :res result; } else res: { + if (func_ty.fnIsGeneric()) { + return sema.mod.fail(&block.base, func_src, "TODO implement generic fn call", .{}); + } try sema.requireRuntimeBlock(block, call_src); try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Call).Struct.fields.len + args.len); @@ -3208,6 +3214,7 @@ fn zirFunc( false, src_locs, null, + &.{}, ); } @@ -3225,6 +3232,7 @@ fn funcCommon( is_extern: bool, src_locs: Zir.Inst.Func.SrcLocs, opt_lib_name: ?[]const u8, + comptime_bits: []const u32, ) CompileError!Air.Inst.Ref { const src: LazySrcLoc = .{ .node_offset = src_node_offset }; const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = src_node_offset }; @@ -3257,13 +3265,23 @@ fn funcCommon( } } + var any_are_comptime = false; const param_types = try sema.arena.alloc(Type, zir_param_types.len); for (zir_param_types) |param_type, i| { // TODO make a compile error from `resolveType` report the source location // of the specific parameter. Will need to take a similar strategy as // `resolveSwitchItemVal` to avoid resolving the source location unless // we actually need to report an error. - param_types[i] = try sema.resolveType(block, src, param_type); + const param_src = src; + param_types[i] = try sema.resolveType(block, param_src, param_type); + + any_are_comptime = any_are_comptime or blk: { + if (comptime_bits.len == 0) + break :blk false; + const bag = comptime_bits[i / 32]; + const is_comptime = @truncate(u1, bag >> @intCast(u5, i % 32)) != 0; + break :blk is_comptime; + }; } if (align_val.tag() != .null_value) { @@ -3286,6 +3304,7 @@ fn funcCommon( .return_type = return_type, .cc = cc, .is_var_args = var_args, + .is_generic = any_are_comptime, }); }; @@ -6526,6 +6545,13 @@ fn zirFuncExtended( break :blk align_tv.val; } else Value.initTag(.null_value); + const comptime_bits: []const u32 = if (!small.has_comptime_bits) &.{} else blk: { + const amt = (extra.data.param_types_len + 31) / 32; + const bit_bags = sema.code.extra[extra_index..][0..amt]; + extra_index += amt; + break :blk bit_bags; + }; + const param_types = sema.code.refSlice(extra_index, extra.data.param_types_len); extra_index += param_types.len; @@ -6554,6 +6580,7 @@ fn zirFuncExtended( is_extern, src_locs, lib_name, + comptime_bits, ); } |
