diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2023-05-02 20:01:32 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2023-06-10 20:40:03 -0700 |
| commit | 50f33734c6cec10a0132644c08ee443c2dd224e2 (patch) | |
| tree | d5192de4e7f849226b93cf03095a5ac7e54c3782 /src | |
| parent | 00f82f1c46126f1fc6655c6142ef16e8e5afbf4e (diff) | |
| download | zig-50f33734c6cec10a0132644c08ee443c2dd224e2.tar.gz zig-50f33734c6cec10a0132644c08ee443c2dd224e2.zip | |
stage2: isGenericPoison InternPool awareness
Diffstat (limited to 'src')
| -rw-r--r-- | src/Module.zig | 2 | ||||
| -rw-r--r-- | src/Sema.zig | 44 | ||||
| -rw-r--r-- | src/type.zig | 24 | ||||
| -rw-r--r-- | src/value.zig | 8 |
4 files changed, 47 insertions, 31 deletions
diff --git a/src/Module.zig b/src/Module.zig index 4187ac206b..a4ae107bed 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -5728,7 +5728,7 @@ pub fn analyzeFnBody(mod: *Module, func: *Fn, arena: Allocator) SemaError!Air { const param_ty = if (func.comptime_args) |comptime_args| t: { const arg_tv = comptime_args[total_param_index]; - const arg_val = if (arg_tv.val.tag() != .generic_poison) + const arg_val = if (!arg_tv.val.isGenericPoison()) arg_tv.val else if (arg_tv.ty.onePossibleValue(mod)) |opv| opv diff --git a/src/Sema.zig b/src/Sema.zig index 540474c84a..45da0927cd 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -300,7 +300,7 @@ pub const Block = struct { const src_decl = sema.mod.declPtr(rt.block.src_decl); break :blk rt.func_src.toSrcLoc(src_decl); }; - if (rt.return_ty.tag() == .generic_poison) { + if (rt.return_ty.isGenericPoison()) { return sema.mod.errNoteNonLazy(src_loc, parent, prefix ++ "the generic function was instantiated with a comptime-only return type", .{}); } try sema.mod.errNoteNonLazy( @@ -1730,7 +1730,7 @@ pub fn resolveInst(sema: *Sema, zir_ref: Zir.Inst.Ref) !Air.Inst.Ref { // The last section of indexes refers to the map of ZIR => AIR. const inst = sema.inst_map.get(i - InternPool.static_len).?; const ty = sema.typeOf(inst); - if (ty.tag() == .generic_poison) return error.GenericPoison; + if (ty.isGenericPoison()) return error.GenericPoison; return inst; } @@ -1766,7 +1766,7 @@ pub fn resolveType(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Ins const air_inst = try sema.resolveInst(zir_ref); assert(air_inst != .var_args_param_type); const ty = try sema.analyzeAsType(block, src, air_inst); - if (ty.tag() == .generic_poison) return error.GenericPoison; + if (ty.isGenericPoison()) return error.GenericPoison; return ty; } @@ -1827,7 +1827,7 @@ fn resolveValue( reason: []const u8, ) CompileError!Value { if (try sema.resolveMaybeUndefValAllowVariables(air_ref)) |val| { - if (val.tag() == .generic_poison) return error.GenericPoison; + if (val.isGenericPoison()) return error.GenericPoison; return val; } return sema.failWithNeededComptime(block, src, reason); @@ -6549,8 +6549,8 @@ const GenericCallAdapter = struct { const other_comptime_args = other_key.comptime_args.?; for (other_comptime_args[0..ctx.func_ty_info.param_types.len], 0..) |other_arg, i| { const this_arg = ctx.args[i]; - const this_is_comptime = this_arg.val.tag() != .generic_poison; - const other_is_comptime = other_arg.val.tag() != .generic_poison; + const this_is_comptime = !this_arg.val.isGenericPoison(); + const other_is_comptime = !other_arg.val.isGenericPoison(); const this_is_anytype = this_arg.is_anytype; const other_is_anytype = other_key.isAnytypeParam(ctx.module, @intCast(u32, i)); @@ -7189,7 +7189,7 @@ fn analyzeInlineCallArg( const param_body = sema.code.extra[extra.end..][0..extra.data.body_len]; const param_ty = param_ty: { const raw_param_ty = raw_param_types[arg_i.*]; - if (raw_param_ty.tag() != .generic_poison) break :param_ty raw_param_ty; + if (!raw_param_ty.isGenericPoison()) break :param_ty raw_param_ty; const param_ty_inst = try sema.resolveBody(param_block, param_body, inst); break :param_ty try sema.analyzeAsType(param_block, param_src, param_ty_inst); }; @@ -7317,7 +7317,7 @@ fn analyzeGenericCallArg( runtime_i: *u32, ) !void { const mod = sema.mod; - const is_runtime = comptime_arg.val.tag() == .generic_poison and + const is_runtime = comptime_arg.val.isGenericPoison() and comptime_arg.ty.hasRuntimeBits(mod) and !(try sema.typeRequiresComptime(comptime_arg.ty)); if (is_runtime) { @@ -8882,7 +8882,7 @@ fn funcCommon( const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = src_node_offset }; const func_src = LazySrcLoc.nodeOffset(src_node_offset); - var is_generic = bare_return_type.tag() == .generic_poison or + var is_generic = bare_return_type.isGenericPoison() or alignment == null or address_space == null or section == .generic or @@ -8965,7 +8965,7 @@ fn funcCommon( var ret_ty_requires_comptime = false; const ret_poison = if (sema.typeRequiresComptime(bare_return_type)) |ret_comptime| rp: { ret_ty_requires_comptime = ret_comptime; - break :rp bare_return_type.tag() == .generic_poison; + break :rp bare_return_type.isGenericPoison(); } else |err| switch (err) { error.GenericPoison => rp: { is_generic = true; @@ -9208,7 +9208,7 @@ fn analyzeParameter( const mod = sema.mod; const requires_comptime = try sema.typeRequiresComptime(param.ty); comptime_params[i] = param.is_comptime or requires_comptime; - const this_generic = param.ty.tag() == .generic_poison; + const this_generic = param.ty.isGenericPoison(); is_generic.* = is_generic.* or this_generic; const target = mod.getTarget(); if (param.is_comptime and !Type.fnCallingConventionAllowsZigTypes(target, cc)) { @@ -15872,7 +15872,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai const param_vals = try params_anon_decl.arena().alloc(Value, info.param_types.len); for (param_vals, 0..) |*param_val, i| { const param_ty = info.param_types[i]; - const is_generic = param_ty.tag() == .generic_poison; + const is_generic = param_ty.isGenericPoison(); const param_ty_val = if (is_generic) Value.null else @@ -15936,7 +15936,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai }); }; - const ret_ty_opt = if (info.return_type.tag() != .generic_poison) + const ret_ty_opt = if (!info.return_type.isGenericPoison()) try Value.Tag.opt_payload.create( sema.arena, try Value.Tag.ty.create(sema.arena, info.return_type), @@ -16713,7 +16713,7 @@ fn zirTypeofBuiltin(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr const operand = try sema.resolveBody(&child_block, body, inst); const operand_ty = sema.typeOf(operand); - if (operand_ty.tag() == .generic_poison) return error.GenericPoison; + if (operand_ty.isGenericPoison()) return error.GenericPoison; return sema.addType(operand_ty); } @@ -17589,7 +17589,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air } return err; }; - if (ty.tag() == .generic_poison) return error.GenericPoison; + if (ty.isGenericPoison()) return error.GenericPoison; break :blk ty; }; const target = sema.mod.getTarget(); @@ -22575,7 +22575,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A extra_index += body.len; const val = try sema.resolveGenericBody(block, align_src, body, inst, Type.u29, "alignment must be comptime-known"); - if (val.tag() == .generic_poison) { + if (val.isGenericPoison()) { break :blk null; } const alignment = @intCast(u32, val.toUnsignedInt(mod)); @@ -22611,7 +22611,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A const addrspace_ty = try sema.getBuiltinType("AddressSpace"); const val = try sema.resolveGenericBody(block, addrspace_src, body, inst, addrspace_ty, "addrespace must be comptime-known"); - if (val.tag() == .generic_poison) { + if (val.isGenericPoison()) { break :blk null; } break :blk val.toEnum(std.builtin.AddressSpace); @@ -22635,7 +22635,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A const ty = Type.initTag(.const_slice_u8); const val = try sema.resolveGenericBody(block, section_src, body, inst, ty, "linksection must be comptime-known"); - if (val.tag() == .generic_poison) { + if (val.isGenericPoison()) { break :blk FuncLinkSection{ .generic = {} }; } break :blk FuncLinkSection{ .explicit = try val.toAllocatedBytes(ty, sema.arena, sema.mod) }; @@ -22659,7 +22659,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A const cc_ty = try sema.getBuiltinType("CallingConvention"); const val = try sema.resolveGenericBody(block, cc_src, body, inst, cc_ty, "calling convention must be comptime-known"); - if (val.tag() == .generic_poison) { + if (val.isGenericPoison()) { break :blk null; } break :blk val.toEnum(std.builtin.CallingConvention); @@ -31790,7 +31790,7 @@ fn resolveInferredErrorSet( // if ies declared by a inline function with generic return type, the return_type should be generic_poison, // because inline function does not create a new declaration, and the ies has been filled with analyzeCall, // so here we can simply skip this case. - if (ies_func_info.return_type.tag() == .generic_poison) { + if (ies_func_info.return_type.isGenericPoison()) { assert(ies_func_info.cc == .Inline); } else if (ies_func_info.return_type.errorUnionSet().castTag(.error_set_inferred).?.data == ies) { if (ies_func_info.is_generic) { @@ -32048,7 +32048,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void else => |e| return e, }; }; - if (field_ty.tag() == .generic_poison) { + if (field_ty.isGenericPoison()) { return error.GenericPoison; } @@ -32442,7 +32442,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { else => |e| return e, }; - if (field_ty.tag() == .generic_poison) { + if (field_ty.isGenericPoison()) { return error.GenericPoison; } diff --git a/src/type.zig b/src/type.zig index 94fd4c2eaf..9f14619c2c 100644 --- a/src/type.zig +++ b/src/type.zig @@ -727,8 +727,8 @@ pub const Type = struct { const a_info = a.fnInfo(); const b_info = b.fnInfo(); - if (a_info.return_type.tag() != .generic_poison and - b_info.return_type.tag() != .generic_poison and + if (!a_info.return_type.isGenericPoison() and + !b_info.return_type.isGenericPoison() and !eql(a_info.return_type, b_info.return_type, mod)) return false; @@ -758,8 +758,8 @@ pub const Type = struct { if (a_info.comptime_params[i] != b_info.comptime_params[i]) return false; - if (a_param_ty.tag() == .generic_poison) continue; - if (b_param_ty.tag() == .generic_poison) continue; + if (a_param_ty.isGenericPoison()) continue; + if (b_param_ty.isGenericPoison()) continue; if (!eql(a_param_ty, b_param_ty, mod)) return false; @@ -1131,7 +1131,7 @@ pub const Type = struct { std.hash.autoHash(hasher, std.builtin.TypeId.Fn); const fn_info = ty.fnInfo(); - if (fn_info.return_type.tag() != .generic_poison) { + if (!fn_info.return_type.isGenericPoison()) { hashWithHasher(fn_info.return_type, hasher, mod); } if (!fn_info.align_is_generic) { @@ -1148,7 +1148,7 @@ pub const Type = struct { std.hash.autoHash(hasher, fn_info.param_types.len); for (fn_info.param_types, 0..) |param_ty, i| { std.hash.autoHash(hasher, fn_info.paramIsComptime(i)); - if (param_ty.tag() == .generic_poison) continue; + if (param_ty.isGenericPoison()) continue; hashWithHasher(param_ty, hasher, mod); } }, @@ -2154,7 +2154,7 @@ pub const Type = struct { if (std.math.cast(u5, i)) |index| if (@truncate(u1, fn_info.noalias_bits >> index) != 0) { try writer.writeAll("noalias "); }; - if (param_ty.tag() == .generic_poison) { + if (param_ty.isGenericPoison()) { try writer.writeAll("anytype"); } else { try print(param_ty, writer, mod); @@ -2175,7 +2175,7 @@ pub const Type = struct { try writer.writeAll(@tagName(fn_info.cc)); try writer.writeAll(") "); } - if (fn_info.return_type.tag() == .generic_poison) { + if (fn_info.return_type.isGenericPoison()) { try writer.writeAll("anytype"); } else { try print(fn_info.return_type, writer, mod); @@ -6075,6 +6075,14 @@ pub const Type = struct { } } + pub fn isGenericPoison(ty: Type) bool { + return switch (ty.ip_index) { + .generic_poison_type => true, + .none => ty.tag() == .generic_poison, + else => false, + }; + } + /// This enum does not directly correspond to `std.builtin.TypeId` because /// it has extra enum tags in it, as a way of using less memory. For example, /// even though Zig recognizes `*align(10) i32` and `*i32` both as Pointer types diff --git a/src/value.zig b/src/value.zig index 8c824b0720..d89be35d85 100644 --- a/src/value.zig +++ b/src/value.zig @@ -5416,6 +5416,14 @@ pub const Value = struct { return initPayload(&value_buffer.base); } + pub fn isGenericPoison(val: Value) bool { + return switch (val.ip_index) { + .generic_poison => true, + .none => val.tag() == .generic_poison, + else => false, + }; + } + /// This type is not copyable since it may contain pointers to its inner data. pub const Payload = struct { tag: Tag, |
