authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-09-25 22:18:43-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-09-25 22:18:43-07:00
log1f2f9f05c254374044d8c30cce6f299d7a18da72
tree868df45684a4db5f092b4106e7b17ddb05fbda1e
parent04366576ea4be4959b596ebff7041d17e18d08d8

stage2: implement zirCoerceResultPtr

and remove Module.simplePtrType and Module.ptrType in favor of `Type.ptr`.

5 files changed, 239 insertions(+), 271 deletions(-)

src/Module.zig-76
......@@ -4460,82 +4460,6 @@ pub fn failWithOwnedErrorMsg(mod: *Module, scope: *Scope, err_msg: *ErrorMsg) Co
44604460 return error.AnalysisFail;
44614461}
44624462
4463pub fn simplePtrType(
4464 arena: *Allocator,
4465 elem_ty: Type,
4466 mutable: bool,
4467 size: std.builtin.TypeInfo.Pointer.Size,
4468 @"addrspace": std.builtin.AddressSpace,
4469) Allocator.Error!Type {
4470 return ptrType(
4471 arena,
4472 elem_ty,
4473 null,
4474 0,
4475 @"addrspace",
4476 0,
4477 0,
4478 mutable,
4479 false,
4480 false,
4481 size,
4482 );
4483}
4484
4485pub fn ptrType(
4486 arena: *Allocator,
4487 elem_ty: Type,
4488 sentinel: ?Value,
4489 @"align": u32,
4490 @"addrspace": std.builtin.AddressSpace,
4491 bit_offset: u16,
4492 host_size: u16,
4493 mutable: bool,
4494 @"allowzero": bool,
4495 @"volatile": bool,
4496 size: std.builtin.TypeInfo.Pointer.Size,
4497) Allocator.Error!Type {
4498 assert(host_size == 0 or bit_offset < host_size * 8);
4499
4500 if (sentinel != null or @"align" != 0 or @"addrspace" != .generic or
4501 bit_offset != 0 or host_size != 0 or @"allowzero" or @"volatile")
4502 {
4503 return Type.Tag.pointer.create(arena, .{
4504 .pointee_type = elem_ty,
4505 .sentinel = sentinel,
4506 .@"align" = @"align",
4507 .@"addrspace" = @"addrspace",
4508 .bit_offset = bit_offset,
4509 .host_size = host_size,
4510 .@"allowzero" = @"allowzero",
4511 .mutable = mutable,
4512 .@"volatile" = @"volatile",
4513 .size = size,
4514 });
4515 }
4516
4517 if (!mutable and size == .Slice and elem_ty.eql(Type.initTag(.u8))) {
4518 return Type.initTag(.const_slice_u8);
4519 }
4520
4521 // TODO stage1 type inference bug
4522 const T = Type.Tag;
4523
4524 const type_payload = try arena.create(Type.Payload.ElemType);
4525 type_payload.* = .{
4526 .base = .{
4527 .tag = switch (size) {
4528 .One => if (mutable) T.single_mut_pointer else T.single_const_pointer,
4529 .Many => if (mutable) T.many_mut_pointer else T.many_const_pointer,
4530 .C => if (mutable) T.c_mut_pointer else T.c_const_pointer,
4531 .Slice => if (mutable) T.mut_slice else T.const_slice,
4532 },
4533 },
4534 .data = elem_ty,
4535 };
4536 return Type.initPayload(&type_payload.base);
4537}
4538
45394463pub fn optionalType(arena: *Allocator, child_type: Type) Allocator.Error!Type {
45404464 switch (child_type.tag()) {
45414465 .single_const_pointer => return Type.Tag.optional_single_const_pointer.create(
src/Sema.zig+149-157
......@@ -979,10 +979,38 @@ fn zirBitcastResultPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) C
979979}
980980
981981fn zirCoerceResultPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
982 _ = inst;
983982 const tracy = trace(@src());
984983 defer tracy.end();
985 return sema.mod.fail(&block.base, sema.src, "TODO implement zirCoerceResultPtr", .{});
984
985 const src: LazySrcLoc = sema.src;
986 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
987 const pointee_ty = try sema.resolveType(block, src, bin_inst.lhs);
988 const ptr = sema.resolveInst(bin_inst.rhs);
989
990 // Create a runtime bitcast instruction with exactly the type the pointer wants.
991 const ptr_ty = try Type.ptr(sema.arena, .{
992 .pointee_type = pointee_ty,
993 .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .local),
994 });
995 try sema.requireRuntimeBlock(block, src);
996 const bitcasted_ptr = try block.addTyOp(.bitcast, ptr_ty, ptr);
997
998 if (Air.refToIndex(ptr)) |ptr_inst| {
999 if (sema.air_instructions.items(.tag)[ptr_inst] == .constant) {
1000 const air_datas = sema.air_instructions.items(.data);
1001 const ptr_val = sema.air_values.items[air_datas[ptr_inst].ty_pl.payload];
1002 if (ptr_val.castTag(.inferred_alloc)) |inferred_alloc| {
1003 // Add the stored instruction to the set we will use to resolve peer types
1004 // for the inferred allocation.
1005 // This instruction will not make it to codegen; it is only to participate
1006 // in the `stored_inst_list` of the `inferred_alloc`.
1007 const operand = try block.addTyOp(.bitcast, pointee_ty, .void_value);
1008 try inferred_alloc.data.stored_inst_list.append(sema.arena, operand);
1009 }
1010 }
1011 }
1012
1013 return bitcasted_ptr;
9861014}
9871015
9881016pub fn analyzeStructDecl(
......@@ -1427,13 +1455,10 @@ fn zirRetPtr(
14271455 return sema.analyzeComptimeAlloc(block, sema.fn_ret_ty);
14281456 }
14291457
1430 const ptr_type = try Module.simplePtrType(
1431 sema.arena,
1432 sema.fn_ret_ty,
1433 true,
1434 .One,
1435 target_util.defaultAddressSpace(sema.mod.getTarget(), .local),
1436 );
1458 const ptr_type = try Type.ptr(sema.arena, .{
1459 .pointee_type = sema.fn_ret_ty,
1460 .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .local),
1461 });
14371462 return block.addTy(.alloc, ptr_type);
14381463}
14391464
......@@ -1581,13 +1606,10 @@ fn zirAlloc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError
15811606 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };
15821607 const var_decl_src = inst_data.src();
15831608 const var_type = try sema.resolveType(block, ty_src, inst_data.operand);
1584 const ptr_type = try Module.simplePtrType(
1585 sema.arena,
1586 var_type,
1587 true,
1588 .One,
1589 target_util.defaultAddressSpace(sema.mod.getTarget(), .local),
1590 );
1609 const ptr_type = try Type.ptr(sema.arena, .{
1610 .pointee_type = var_type,
1611 .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .local),
1612 });
15911613 try sema.requireRuntimeBlock(block, var_decl_src);
15921614 return block.addTy(.alloc, ptr_type);
15931615}
......@@ -1604,13 +1626,10 @@ fn zirAllocMut(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr
16041626 return sema.analyzeComptimeAlloc(block, var_type);
16051627 }
16061628 try sema.validateVarType(block, ty_src, var_type);
1607 const ptr_type = try Module.simplePtrType(
1608 sema.arena,
1609 var_type,
1610 true,
1611 .One,
1612 target_util.defaultAddressSpace(sema.mod.getTarget(), .local),
1613 );
1629 const ptr_type = try Type.ptr(sema.arena, .{
1630 .pointee_type = var_type,
1631 .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .local),
1632 });
16141633 try sema.requireRuntimeBlock(block, var_decl_src);
16151634 return block.addTy(.alloc, ptr_type);
16161635}
......@@ -1670,13 +1689,10 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde
16701689 try sema.mod.declareDeclDependency(sema.owner_decl, decl);
16711690
16721691 const final_elem_ty = try decl.ty.copy(sema.arena);
1673 const final_ptr_ty = try Module.simplePtrType(
1674 sema.arena,
1675 final_elem_ty,
1676 true,
1677 .One,
1678 target_util.defaultAddressSpace(sema.mod.getTarget(), .local),
1679 );
1692 const final_ptr_ty = try Type.ptr(sema.arena, .{
1693 .pointee_type = final_elem_ty,
1694 .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .local),
1695 });
16801696 const final_ptr_ty_inst = try sema.addType(final_ptr_ty);
16811697 sema.air_instructions.items(.data)[ptr_inst].ty_pl.ty = final_ptr_ty_inst;
16821698
......@@ -1698,13 +1714,10 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde
16981714 try sema.validateVarType(block, ty_src, final_elem_ty);
16991715 }
17001716 // Change it to a normal alloc.
1701 const final_ptr_ty = try Module.simplePtrType(
1702 sema.arena,
1703 final_elem_ty,
1704 true,
1705 .One,
1706 target_util.defaultAddressSpace(sema.mod.getTarget(), .local),
1707 );
1717 const final_ptr_ty = try Type.ptr(sema.arena, .{
1718 .pointee_type = final_elem_ty,
1719 .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .local),
1720 });
17081721 sema.air_instructions.set(ptr_inst, .{
17091722 .tag = .alloc,
17101723 .data = .{ .ty = final_ptr_ty },
......@@ -1858,14 +1871,11 @@ fn zirStoreToBlockPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co
18581871 }
18591872 const ptr = sema.resolveInst(bin_inst.lhs);
18601873 const value = sema.resolveInst(bin_inst.rhs);
1861 const ptr_ty = try Module.simplePtrType(
1862 sema.arena,
1863 sema.typeOf(value),
1864 true,
1865 .One,
1874 const ptr_ty = try Type.ptr(sema.arena, .{
1875 .pointee_type = sema.typeOf(value),
18661876 // TODO figure out which address space is appropriate here
1867 target_util.defaultAddressSpace(sema.mod.getTarget(), .local),
1868 );
1877 .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .local),
1878 });
18691879 // TODO detect when this store should be done at compile-time. For example,
18701880 // if expressions should force it when the condition is compile-time known.
18711881 const src: LazySrcLoc = .unneeded;
......@@ -1912,14 +1922,10 @@ fn zirStoreToInferredPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index)
19121922 // for the inferred allocation.
19131923 try inferred_alloc.data.stored_inst_list.append(sema.arena, operand);
19141924 // Create a runtime bitcast instruction with exactly the type the pointer wants.
1915 const ptr_ty = try Module.simplePtrType(
1916 sema.arena,
1917 operand_ty,
1918 true,
1919 .One,
1920 // TODO figure out which address space is appropriate here
1921 target_util.defaultAddressSpace(sema.mod.getTarget(), .local),
1922 );
1925 const ptr_ty = try Type.ptr(sema.arena, .{
1926 .pointee_type = operand_ty,
1927 .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .local),
1928 });
19231929 const bitcasted_ptr = try block.addTyOp(.bitcast, ptr_ty, ptr);
19241930 return sema.storePtr(block, src, bitcasted_ptr, operand);
19251931 }
......@@ -3845,13 +3851,11 @@ fn zirOptionalPayloadPtr(
38453851 }
38463852
38473853 const child_type = try opt_type.optionalChildAlloc(sema.arena);
3848 const child_pointer = try Module.simplePtrType(
3849 sema.arena,
3850 child_type,
3851 !optional_ptr_ty.isConstPtr(),
3852 .One,
3853 optional_ptr_ty.ptrAddressSpace(),
3854 );
3854 const child_pointer = try Type.ptr(sema.arena, .{
3855 .pointee_type = child_type,
3856 .mutable = !optional_ptr_ty.isConstPtr(),
3857 .@"addrspace" = optional_ptr_ty.ptrAddressSpace(),
3858 });
38553859
38563860 if (try sema.resolveDefinedValue(block, src, optional_ptr)) |pointer_val| {
38573861 if (try pointer_val.pointerDeref(sema.arena)) |val| {
......@@ -3966,13 +3970,11 @@ fn zirErrUnionPayloadPtr(
39663970 return sema.mod.fail(&block.base, src, "expected error union type, found {}", .{operand_ty.elemType()});
39673971
39683972 const payload_ty = operand_ty.elemType().errorUnionPayload();
3969 const operand_pointer_ty = try Module.simplePtrType(
3970 sema.arena,
3971 payload_ty,
3972 !operand_ty.isConstPtr(),
3973 .One,
3974 operand_ty.ptrAddressSpace(),
3975 );
3973 const operand_pointer_ty = try Type.ptr(sema.arena, .{
3974 .pointee_type = payload_ty,
3975 .mutable = !operand_ty.isConstPtr(),
3976 .@"addrspace" = operand_ty.ptrAddressSpace(),
3977 });
39763978
39773979 if (try sema.resolveDefinedValue(block, src, operand)) |pointer_val| {
39783980 if (try pointer_val.pointerDeref(sema.arena)) |val| {
......@@ -7306,19 +7308,14 @@ fn zirPtrTypeSimple(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Comp
73067308
73077309 const inst_data = sema.code.instructions.items(.data)[inst].ptr_type_simple;
73087310 const elem_type = try sema.resolveType(block, .unneeded, inst_data.elem_type);
7309 const ty = try Module.ptrType(
7310 sema.arena,
7311 elem_type,
7312 null,
7313 0,
7314 .generic,
7315 0,
7316 0,
7317 inst_data.is_mutable,
7318 inst_data.is_allowzero,
7319 inst_data.is_volatile,
7320 inst_data.size,
7321 );
7311 const ty = try Type.ptr(sema.arena, .{
7312 .pointee_type = elem_type,
7313 .@"addrspace" = .generic,
7314 .mutable = inst_data.is_mutable,
7315 .@"allowzero" = inst_data.is_allowzero,
7316 .@"volatile" = inst_data.is_volatile,
7317 .size = inst_data.size,
7318 });
73227319 return sema.addType(ty);
73237320}
73247321
......@@ -7367,19 +7364,18 @@ fn zirPtrType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr
73677364
73687365 const elem_type = try sema.resolveType(block, .unneeded, extra.data.elem_type);
73697366
7370 const ty = try Module.ptrType(
7371 sema.arena,
7372 elem_type,
7373 sentinel,
7374 abi_align,
7375 address_space,
7376 bit_start,
7377 bit_end,
7378 inst_data.flags.is_mutable,
7379 inst_data.flags.is_allowzero,
7380 inst_data.flags.is_volatile,
7381 inst_data.size,
7382 );
7367 const ty = try Type.ptr(sema.arena, .{
7368 .pointee_type = elem_type,
7369 .sentinel = sentinel,
7370 .@"align" = abi_align,
7371 .@"addrspace" = address_space,
7372 .bit_offset = bit_start,
7373 .host_size = bit_end,
7374 .mutable = inst_data.flags.is_mutable,
7375 .@"allowzero" = inst_data.flags.is_allowzero,
7376 .@"volatile" = inst_data.flags.is_volatile,
7377 .size = inst_data.size,
7378 });
73837379 return sema.addType(ty);
73847380}
73857381
......@@ -8456,19 +8452,15 @@ fn zirMemcpy(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro
84568452 });
84578453 }
84588454 const src_ptr_info = uncasted_src_ptr_ty.ptrInfo().data;
8459 const wanted_src_ptr_ty = try Module.ptrType(
8460 sema.arena,
8461 dest_ptr_ty.elemType2(),
8462 null,
8463 src_ptr_info.@"align",
8464 src_ptr_info.@"addrspace",
8465 0,
8466 0,
8467 false,
8468 src_ptr_info.@"allowzero",
8469 src_ptr_info.@"volatile",
8470 .Many,
8471 );
8455 const wanted_src_ptr_ty = try Type.ptr(sema.arena, .{
8456 .pointee_type = dest_ptr_ty.elemType2(),
8457 .@"align" = src_ptr_info.@"align",
8458 .@"addrspace" = src_ptr_info.@"addrspace",
8459 .mutable = false,
8460 .@"allowzero" = src_ptr_info.@"allowzero",
8461 .@"volatile" = src_ptr_info.@"volatile",
8462 .size = .Many,
8463 });
84728464 const src_ptr = try sema.coerce(block, wanted_src_ptr_ty, uncasted_src_ptr, src_src);
84738465 const len = try sema.coerce(block, Type.initTag(.usize), sema.resolveInst(extra.byte_count), len_src);
84748466
......@@ -8922,13 +8914,10 @@ fn panicWithMsg(
89228914 const panic_fn = try sema.getBuiltin(block, src, "panic");
89238915 const unresolved_stack_trace_ty = try sema.getBuiltinType(block, src, "StackTrace");
89248916 const stack_trace_ty = try sema.resolveTypeFields(block, src, unresolved_stack_trace_ty);
8925 const ptr_stack_trace_ty = try Module.simplePtrType(
8926 arena,
8927 stack_trace_ty,
8928 true,
8929 .One,
8930 target_util.defaultAddressSpace(sema.mod.getTarget(), .global_constant), // TODO might need a place that is more dynamic
8931 );
8917 const ptr_stack_trace_ty = try Type.ptr(arena, .{
8918 .pointee_type = stack_trace_ty,
8919 .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .global_constant), // TODO might need a place that is more dynamic
8920 });
89328921 const null_stack_trace = try sema.addConstant(
89338922 try Module.optionalType(arena, ptr_stack_trace_ty),
89348923 Value.initTag(.null_value),
......@@ -9407,13 +9396,11 @@ fn structFieldPtr(
94079396 const field_index = struct_obj.fields.getIndex(field_name) orelse
94089397 return sema.failWithBadFieldAccess(block, struct_obj, field_name_src, field_name);
94099398 const field = struct_obj.fields.values()[field_index];
9410 const ptr_field_ty = try Module.simplePtrType(
9411 arena,
9412 field.ty,
9413 struct_ptr_ty.ptrIsMutable(),
9414 .One,
9415 struct_ptr_ty.ptrAddressSpace(),
9416 );
9399 const ptr_field_ty = try Type.ptr(arena, .{
9400 .pointee_type = field.ty,
9401 .mutable = struct_ptr_ty.ptrIsMutable(),
9402 .@"addrspace" = struct_ptr_ty.ptrAddressSpace(),
9403 });
94179404
94189405 if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| {
94199406 return sema.addConstant(
......@@ -9512,13 +9499,11 @@ fn unionFieldPtr(
95129499 return sema.failWithBadUnionFieldAccess(block, union_obj, field_name_src, field_name);
95139500
95149501 const field = union_obj.fields.values()[field_index];
9515 const ptr_field_ty = try Module.simplePtrType(
9516 arena,
9517 field.ty,
9518 union_ptr_ty.ptrIsMutable(),
9519 .One,
9520 union_ptr_ty.ptrAddressSpace(),
9521 );
9502 const ptr_field_ty = try Type.ptr(arena, .{
9503 .pointee_type = field.ty,
9504 .mutable = union_ptr_ty.ptrIsMutable(),
9505 .@"addrspace" = union_ptr_ty.ptrAddressSpace(),
9506 });
95229507
95239508 if (try sema.resolveDefinedValue(block, src, union_ptr)) |union_ptr_val| {
95249509 // TODO detect inactive union field and emit compile error
......@@ -9694,13 +9679,11 @@ fn elemPtrArray(
96949679) CompileError!Air.Inst.Ref {
96959680 const array_ptr_ty = sema.typeOf(array_ptr);
96969681 const pointee_type = array_ptr_ty.elemType().elemType();
9697 const result_ty = try Module.simplePtrType(
9698 sema.arena,
9699 pointee_type,
9700 array_ptr_ty.ptrIsMutable(),
9701 .One,
9702 array_ptr_ty.ptrAddressSpace(),
9703 );
9682 const result_ty = try Type.ptr(sema.arena, .{
9683 .pointee_type = pointee_type,
9684 .mutable = array_ptr_ty.ptrIsMutable(),
9685 .@"addrspace" = array_ptr_ty.ptrAddressSpace(),
9686 });
97049687
97059688 if (try sema.resolveDefinedValue(block, src, array_ptr)) |array_ptr_val| {
97069689 if (try sema.resolveDefinedValue(block, elem_index_src, elem_index)) |index_val| {
......@@ -10243,11 +10226,19 @@ fn analyzeDeclRef(sema: *Sema, decl: *Decl) CompileError!Air.Inst.Ref {
1024310226 const decl_tv = try decl.typedValue();
1024410227 if (decl_tv.val.castTag(.variable)) |payload| {
1024510228 const variable = payload.data;
10246 const ty = try Module.simplePtrType(sema.arena, decl_tv.ty, variable.is_mutable, .One, decl.@"addrspace");
10229 const ty = try Type.ptr(sema.arena, .{
10230 .pointee_type = decl_tv.ty,
10231 .mutable = variable.is_mutable,
10232 .@"addrspace" = decl.@"addrspace",
10233 });
1024710234 return sema.addConstant(ty, try Value.Tag.decl_ref.create(sema.arena, decl));
1024810235 }
1024910236 return sema.addConstant(
10250 try Module.simplePtrType(sema.arena, decl_tv.ty, false, .One, decl.@"addrspace"),
10237 try Type.ptr(sema.arena, .{
10238 .pointee_type = decl_tv.ty,
10239 .mutable = false,
10240 .@"addrspace" = decl.@"addrspace",
10241 }),
1025110242 try Value.Tag.decl_ref.create(sema.arena, decl),
1025210243 );
1025310244}
......@@ -10271,8 +10262,15 @@ fn analyzeRef(
1027110262
1027210263 try sema.requireRuntimeBlock(block, src);
1027310264 const address_space = target_util.defaultAddressSpace(sema.mod.getTarget(), .local);
10274 const ptr_type = try Module.simplePtrType(sema.arena, operand_ty, false, .One, address_space);
10275 const mut_ptr_type = try Module.simplePtrType(sema.arena, operand_ty, true, .One, address_space);
10265 const ptr_type = try Type.ptr(sema.arena, .{
10266 .pointee_type = operand_ty,
10267 .mutable = false,
10268 .@"addrspace" = address_space,
10269 });
10270 const mut_ptr_type = try Type.ptr(sema.arena, .{
10271 .pointee_type = operand_ty,
10272 .@"addrspace" = address_space,
10273 });
1027610274 const alloc = try block.addTy(.alloc, mut_ptr_type);
1027710275 try sema.storePtr(block, src, alloc, operand);
1027810276
......@@ -10428,19 +10426,16 @@ fn analyzeSlice(
1042810426 }
1042910427 }
1043010428 }
10431 const return_type = try Module.ptrType(
10432 sema.arena,
10433 return_elem_type,
10434 if (end_opt == .none) slice_sentinel else null,
10435 0, // TODO alignment
10436 if (ptr_child.zigTypeTag() == .Pointer) ptr_child.ptrAddressSpace() else .generic,
10437 0,
10438 0,
10439 !ptr_child.isConstPtr(),
10440 ptr_child.isAllowzeroPtr(),
10441 ptr_child.isVolatilePtr(),
10442 return_ptr_size,
10443 );
10429 const return_type = try Type.ptr(sema.arena, .{
10430 .pointee_type = return_elem_type,
10431 .sentinel = if (end_opt == .none) slice_sentinel else null,
10432 .@"align" = 0, // TODO alignment
10433 .@"addrspace" = if (ptr_child.zigTypeTag() == .Pointer) ptr_child.ptrAddressSpace() else .generic,
10434 .mutable = !ptr_child.isConstPtr(),
10435 .@"allowzero" = ptr_child.isAllowzeroPtr(),
10436 .@"volatile" = ptr_child.isVolatilePtr(),
10437 .size = return_ptr_size,
10438 });
1044410439 _ = return_type;
1044510440
1044610441 return sema.mod.fail(&block.base, src, "TODO implement analysis of slice", .{});
......@@ -11626,13 +11621,10 @@ fn analyzeComptimeAlloc(
1162611621 block: *Scope.Block,
1162711622 var_type: Type,
1162811623) CompileError!Air.Inst.Ref {
11629 const ptr_type = try Module.simplePtrType(
11630 sema.arena,
11631 var_type,
11632 true,
11633 .One,
11634 target_util.defaultAddressSpace(sema.mod.getTarget(), .global_constant),
11635 );
11624 const ptr_type = try Type.ptr(sema.arena, .{
11625 .pointee_type = var_type,
11626 .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .global_constant),
11627 });
1163611628
1163711629 var anon_decl = try block.startAnonDecl();
1163811630 defer anon_decl.deinit();
src/type.zig+48-13
......@@ -3652,12 +3652,12 @@ pub const Type = extern union {
36523652 }
36533653
36543654 pub fn create(comptime t: Tag, ally: *Allocator, data: Data(t)) error{OutOfMemory}!file_struct.Type {
3655 const ptr = try ally.create(t.Type());
3656 ptr.* = .{
3655 const p = try ally.create(t.Type());
3656 p.* = .{
36573657 .base = .{ .tag = t },
36583658 .data = data,
36593659 };
3660 return file_struct.Type{ .ptr_otherwise = &ptr.base };
3660 return file_struct.Type{ .ptr_otherwise = &p.base };
36613661 }
36623662
36633663 pub fn Data(comptime t: Tag) type {
......@@ -3747,19 +3747,23 @@ pub const Type = extern union {
37473747 pub const base_tag = Tag.pointer;
37483748
37493749 base: Payload = Payload{ .tag = base_tag },
3750 data: struct {
3750 data: Data,
3751
3752 pub const Data = struct {
37513753 pointee_type: Type,
3752 sentinel: ?Value,
3754 sentinel: ?Value = null,
37533755 /// If zero use pointee_type.AbiAlign()
3754 @"align": u32,
3756 @"align": u32 = 0,
3757 /// See src/target.zig defaultAddressSpace function for how to obtain
3758 /// an appropriate value for this field.
37553759 @"addrspace": std.builtin.AddressSpace,
3756 bit_offset: u16,
3757 host_size: u16,
3758 @"allowzero": bool,
3759 mutable: bool,
3760 @"volatile": bool,
3761 size: std.builtin.TypeInfo.Pointer.Size,
3762 },
3760 bit_offset: u16 = 0,
3761 host_size: u16 = 0,
3762 @"allowzero": bool = false,
3763 mutable: bool = true, // TODO change this to const, not mutable
3764 @"volatile": bool = false,
3765 size: std.builtin.TypeInfo.Pointer.Size = .One,
3766 };
37633767 };
37643768
37653769 pub const ErrorUnion = struct {
......@@ -3815,6 +3819,37 @@ pub const Type = extern union {
38153819 data: *Module.EnumSimple,
38163820 };
38173821 };
3822
3823 pub fn ptr(arena: *Allocator, d: Payload.Pointer.Data) !Type {
3824 assert(d.host_size == 0 or d.bit_offset < d.host_size * 8);
3825
3826 if (d.sentinel != null or d.@"align" != 0 or d.@"addrspace" != .generic or
3827 d.bit_offset != 0 or d.host_size != 0 or d.@"allowzero" or d.@"volatile")
3828 {
3829 return Type.Tag.pointer.create(arena, d);
3830 }
3831
3832 if (!d.mutable and d.size == .Slice and d.pointee_type.eql(Type.initTag(.u8))) {
3833 return Type.initTag(.const_slice_u8);
3834 }
3835
3836 // TODO stage1 type inference bug
3837 const T = Type.Tag;
3838
3839 const type_payload = try arena.create(Type.Payload.ElemType);
3840 type_payload.* = .{
3841 .base = .{
3842 .tag = switch (d.size) {
3843 .One => if (d.mutable) T.single_mut_pointer else T.single_const_pointer,
3844 .Many => if (d.mutable) T.many_mut_pointer else T.many_const_pointer,
3845 .C => if (d.mutable) T.c_mut_pointer else T.c_const_pointer,
3846 .Slice => if (d.mutable) T.mut_slice else T.const_slice,
3847 },
3848 },
3849 .data = d.pointee_type,
3850 };
3851 return Type.initPayload(&type_payload.base);
3852 }
38183853};
38193854
38203855pub const CType = enum {
test/behavior/struct.zig+38
......@@ -52,3 +52,41 @@ fn testFoo(foo: StructFoo) !void {
5252fn testMutation(foo: *StructFoo) void {
5353 foo.c = 100;
5454}
55
56test "struct byval assign" {
57 var foo1: StructFoo = undefined;
58 var foo2: StructFoo = undefined;
59
60 foo1.a = 1234;
61 foo2.a = 0;
62 try expect(foo2.a == 0);
63 foo2 = foo1;
64 try expect(foo2.a == 1234);
65}
66
67const Node = struct {
68 val: Val,
69 next: *Node,
70};
71
72const Val = struct {
73 x: i32,
74};
75
76test "struct initializer" {
77 const val = Val{ .x = 42 };
78 try expect(val.x == 42);
79}
80
81const MemberFnTestFoo = struct {
82 x: i32,
83 fn member(foo: MemberFnTestFoo) i32 {
84 return foo.x;
85 }
86};
87
88test "call member function directly" {
89 const instance = MemberFnTestFoo{ .x = 1234 };
90 const result = MemberFnTestFoo.member(instance);
91 try expect(result == 1234);
92}
test/behavior/struct_stage1.zig+4-25
......@@ -5,6 +5,7 @@ const expect = std.testing.expect;
55const expectEqual = std.testing.expectEqual;
66const expectEqualSlices = std.testing.expectEqualSlices;
77const maxInt = std.math.maxInt;
8
89top_level_field: i32,
910
1011test "top level fields" {
......@@ -58,22 +59,6 @@ test "struct point to self" {
5859 try expect(node.next.next.next.val.x == 1);
5960}
6061
61test "struct byval assign" {
62 var foo1: StructFoo = undefined;
63 var foo2: StructFoo = undefined;
64
65 foo1.a = 1234;
66 foo2.a = 0;
67 try expect(foo2.a == 0);
68 foo2 = foo1;
69 try expect(foo2.a == 1234);
70}
71
72test "struct initializer" {
73 const val = Val{ .x = 42 };
74 try expect(val.x == 42);
75}
76
7762test "fn call of struct field" {
7863 const Foo = struct {
7964 ptr: fn () i32,
......@@ -91,22 +76,16 @@ test "fn call of struct field" {
9176 try expect(S.callStructField(Foo{ .ptr = S.aFunc }) == 13);
9277}
9378
94test "store member function in variable" {
95 const instance = MemberFnTestFoo{ .x = 1234 };
96 const memberFn = MemberFnTestFoo.member;
97 const result = memberFn(instance);
98 try expect(result == 1234);
99}
10079const MemberFnTestFoo = struct {
10180 x: i32,
10281 fn member(foo: MemberFnTestFoo) i32 {
10382 return foo.x;
10483 }
10584};
106
107test "call member function directly" {
85test "store member function in variable" {
10886 const instance = MemberFnTestFoo{ .x = 1234 };
109 const result = MemberFnTestFoo.member(instance);
87 const memberFn = MemberFnTestFoo.member;
88 const result = memberFn(instance);
11089 try expect(result == 1234);
11190}
11291