diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-12-28 20:48:21 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-12-28 23:22:09 -0700 |
| commit | 91619cdf57f54accbdbb3ff616856eaf79b537a3 (patch) | |
| tree | 9da2362e728f068103a1ab83a89411f825a5c10b /src | |
| parent | 2dd725571302a2e6e4101565554e88b4a10b0994 (diff) | |
| download | zig-91619cdf57f54accbdbb3ff616856eaf79b537a3.tar.gz zig-91619cdf57f54accbdbb3ff616856eaf79b537a3.zip | |
Sema: implement calling a fn ptr via a union field
Also, ignore `packed` on unions because that will be removed from the
language.
Diffstat (limited to 'src')
| -rw-r--r-- | src/Module.zig | 3 | ||||
| -rw-r--r-- | src/Sema.zig | 58 |
2 files changed, 36 insertions, 25 deletions
diff --git a/src/Module.zig b/src/Module.zig index 2c5c01bb7a..a1f804c282 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -1104,9 +1104,6 @@ pub const Union = struct { pub fn getLayout(u: Union, target: Target, have_tag: bool) Layout { assert(u.status == .have_layout); - const is_packed = u.layout == .Packed; - if (is_packed) @panic("TODO packed unions"); - var most_aligned_field: usize = undefined; var most_aligned_field_size: u64 = undefined; var biggest_field: usize = undefined; diff --git a/src/Sema.zig b/src/Sema.zig index 2c2ba8bcb5..eca73a88e2 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -12152,34 +12152,16 @@ fn fieldCallBind( const field_index = @intCast(u32, field_index_usize); const field = struct_obj.fields.values()[field_index]; - const ptr_field_ty = try Type.ptr(arena, .{ - .pointee_type = field.ty, - .mutable = ptr_ty.ptrIsMutable(), - .@"addrspace" = ptr_ty.ptrAddressSpace(), - }); - - if (try sema.resolveDefinedValue(block, src, object_ptr)) |struct_ptr_val| { - const pointer = try sema.addConstant( - ptr_field_ty, - try Value.Tag.field_ptr.create(arena, .{ - .container_ptr = struct_ptr_val, - .field_index = field_index, - }), - ); - return sema.analyzeLoad(block, src, pointer, src); - } - - try sema.requireRuntimeBlock(block, src); - const ptr_inst = try block.addStructFieldPtr(object_ptr, field_index, ptr_field_ty); - return sema.analyzeLoad(block, src, ptr_inst, src); + return finishFieldCallBind(sema, block, src, ptr_ty, field.ty, field_index, object_ptr); }, .Union => { const union_ty = try sema.resolveTypeFields(block, src, concrete_ty); const fields = union_ty.unionFields(); const field_index_usize = fields.getIndex(field_name) orelse break :find_field; + const field_index = @intCast(u32, field_index_usize); + const field = fields.values()[field_index]; - _ = field_index_usize; - return sema.fail(block, src, "TODO implement field calls on unions", .{}); + return finishFieldCallBind(sema, block, src, ptr_ty, field.ty, field_index, object_ptr); }, .Type => { const namespace = try sema.analyzeLoad(block, src, object_ptr, src); @@ -12236,6 +12218,38 @@ fn fieldCallBind( return sema.fail(block, src, "type '{}' has no field or member function named '{s}'", .{ concrete_ty, field_name }); } +fn finishFieldCallBind( + sema: *Sema, + block: *Block, + src: LazySrcLoc, + ptr_ty: Type, + field_ty: Type, + field_index: u32, + object_ptr: Air.Inst.Ref, +) CompileError!Air.Inst.Ref { + const arena = sema.arena; + const ptr_field_ty = try Type.ptr(arena, .{ + .pointee_type = field_ty, + .mutable = ptr_ty.ptrIsMutable(), + .@"addrspace" = ptr_ty.ptrAddressSpace(), + }); + + if (try sema.resolveDefinedValue(block, src, object_ptr)) |struct_ptr_val| { + const pointer = try sema.addConstant( + ptr_field_ty, + try Value.Tag.field_ptr.create(arena, .{ + .container_ptr = struct_ptr_val, + .field_index = field_index, + }), + ); + return sema.analyzeLoad(block, src, pointer, src); + } + + try sema.requireRuntimeBlock(block, src); + const ptr_inst = try block.addStructFieldPtr(object_ptr, field_index, ptr_field_ty); + return sema.analyzeLoad(block, src, ptr_inst, src); +} + fn namespaceLookup( sema: *Sema, block: *Block, |
