authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-10-18 15:09:13+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-10-20 03:44:02+02:00
logc507e0b76396a200392e16b92292bfc442c6421f
tree6d6c62c3bc13e503be8805ef59bf932cfc76a081
parent05c5c99a95c894d7e3241e1729e09aa7eacb6035

stage2: Sema.fieldPtr for slice ptr and len


1 files changed, 44 insertions(+), 19 deletions(-)

src/Sema.zig+44-19
......@@ -10897,27 +10897,52 @@ fn fieldPtr(
1089710897 }
1089810898 },
1089910899 .Pointer => if (inner_ty.isSlice()) {
10900 // Here for the ptr and len fields what we need to do is the situation
10901 // when a temporary has its address taken, e.g. `&a[c..d].len`.
10902 // This value may be known at compile-time or runtime. In the former
10903 // case, it should create an anonymous Decl and return a decl_ref to it.
10904 // In the latter case, it should add an `alloc` instruction, store
10905 // the runtime value to it, and then return the `alloc`.
10906 // In both cases the pointer should be const.
10900 const inner_ptr = if (is_pointer_to)
10901 try sema.analyzeLoad(block, src, object_ptr, object_ptr_src)
10902 else
10903 object_ptr;
10904
1090710905 if (mem.eql(u8, field_name, "ptr")) {
10908 return sema.fail(
10909 block,
10910 field_name_src,
10911 "TODO: implement reference to 'ptr' field of slice '{}'",
10912 .{inner_ty},
10913 );
10906 const buf = try sema.arena.create(Type.SlicePtrFieldTypeBuffer);
10907 const slice_ptr_ty = inner_ty.slicePtrFieldType(buf);
10908
10909 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {
10910 var anon_decl = try block.startAnonDecl();
10911 defer anon_decl.deinit();
10912
10913 return sema.analyzeDeclRef(try anon_decl.finish(
10914 try slice_ptr_ty.copy(anon_decl.arena()),
10915 try val.slicePtr().copy(anon_decl.arena()),
10916 ));
10917 }
10918 try sema.requireRuntimeBlock(block, src);
10919
10920 const result_ty = try Type.ptr(sema.arena, .{
10921 .pointee_type = slice_ptr_ty,
10922 .mutable = object_ptr_ty.ptrIsMutable(),
10923 .@"addrspace" = object_ptr_ty.ptrAddressSpace(),
10924 });
10925
10926 return block.addTyOp(.ptr_slice_ptr_ptr, result_ty, inner_ptr);
1091410927 } else if (mem.eql(u8, field_name, "len")) {
10915 return sema.fail(
10916 block,
10917 field_name_src,
10918 "TODO: implement reference to 'len' field of slice '{}'",
10919 .{inner_ty},
10920 );
10928 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {
10929 var anon_decl = try block.startAnonDecl();
10930 defer anon_decl.deinit();
10931
10932 return sema.analyzeDeclRef(try anon_decl.finish(
10933 Type.usize,
10934 try Value.Tag.int_u64.create(anon_decl.arena(), val.sliceLen()),
10935 ));
10936 }
10937 try sema.requireRuntimeBlock(block, src);
10938
10939 const result_ty = try Type.ptr(sema.arena, .{
10940 .pointee_type = Type.usize,
10941 .mutable = object_ptr_ty.ptrIsMutable(),
10942 .@"addrspace" = object_ptr_ty.ptrAddressSpace(),
10943 });
10944
10945 return block.addTyOp(.ptr_slice_len_ptr, result_ty, inner_ptr);
1092110946 } else {
1092210947 return sema.fail(
1092310948 block,