| ... | ... | @@ -16979,44 +16979,44 @@ fn fieldPtr( |
| 16979 | 16979 | const buf = try sema.arena.create(Type.SlicePtrFieldTypeBuffer); |
| 16980 | 16980 | const slice_ptr_ty = inner_ty.slicePtrFieldType(buf); |
| 16981 | 16981 | |
| 16982 | | if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| { |
| 16983 | | var anon_decl = try block.startAnonDecl(src); |
| 16984 | | defer anon_decl.deinit(); |
| 16985 | | |
| 16986 | | return sema.analyzeDeclRef(try anon_decl.finish( |
| 16987 | | try slice_ptr_ty.copy(anon_decl.arena()), |
| 16988 | | try val.slicePtr().copy(anon_decl.arena()), |
| 16989 | | 0, // default alignment |
| 16990 | | )); |
| 16991 | | } |
| 16992 | | try sema.requireRuntimeBlock(block, src); |
| 16993 | | |
| 16994 | 16982 | const result_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 16995 | 16983 | .pointee_type = slice_ptr_ty, |
| 16996 | 16984 | .mutable = object_ptr_ty.ptrIsMutable(), |
| 16997 | 16985 | .@"addrspace" = object_ptr_ty.ptrAddressSpace(), |
| 16998 | 16986 | }); |
| 16999 | 16987 | |
| 17000 | | return block.addTyOp(.ptr_slice_ptr_ptr, result_ty, inner_ptr); |
| 17001 | | } else if (mem.eql(u8, field_name, "len")) { |
| 17002 | 16988 | if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| { |
| 17003 | | var anon_decl = try block.startAnonDecl(src); |
| 17004 | | defer anon_decl.deinit(); |
| 17005 | | |
| 17006 | | return sema.analyzeDeclRef(try anon_decl.finish( |
| 17007 | | Type.usize, |
| 17008 | | try Value.Tag.int_u64.create(anon_decl.arena(), val.sliceLen(sema.mod)), |
| 17009 | | 0, // default alignment |
| 17010 | | )); |
| 16989 | return sema.addConstant( |
| 16990 | result_ty, |
| 16991 | try Value.Tag.field_ptr.create(sema.arena, .{ |
| 16992 | .container_ptr = val, |
| 16993 | .container_ty = inner_ty, |
| 16994 | .field_index = Value.Payload.Slice.ptr_index, |
| 16995 | }), |
| 16996 | ); |
| 17011 | 16997 | } |
| 17012 | 16998 | try sema.requireRuntimeBlock(block, src); |
| 17013 | 16999 | |
| 17000 | return block.addTyOp(.ptr_slice_ptr_ptr, result_ty, inner_ptr); |
| 17001 | } else if (mem.eql(u8, field_name, "len")) { |
| 17014 | 17002 | const result_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 17015 | 17003 | .pointee_type = Type.usize, |
| 17016 | 17004 | .mutable = object_ptr_ty.ptrIsMutable(), |
| 17017 | 17005 | .@"addrspace" = object_ptr_ty.ptrAddressSpace(), |
| 17018 | 17006 | }); |
| 17019 | 17007 | |
| 17008 | if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| { |
| 17009 | return sema.addConstant( |
| 17010 | result_ty, |
| 17011 | try Value.Tag.field_ptr.create(sema.arena, .{ |
| 17012 | .container_ptr = val, |
| 17013 | .container_ty = inner_ty, |
| 17014 | .field_index = Value.Payload.Slice.len_index, |
| 17015 | }), |
| 17016 | ); |
| 17017 | } |
| 17018 | try sema.requireRuntimeBlock(block, src); |
| 17019 | |
| 17020 | 17020 | return block.addTyOp(.ptr_slice_len_ptr, result_ty, inner_ptr); |
| 17021 | 17021 | } else { |
| 17022 | 17022 | return sema.fail( |
| ... | ... | @@ -19297,7 +19297,6 @@ fn beginComptimePtrMutation( |
| 19297 | 19297 | const field_ptr = ptr_val.castTag(.field_ptr).?.data; |
| 19298 | 19298 | var parent = try beginComptimePtrMutation(sema, block, src, field_ptr.container_ptr); |
| 19299 | 19299 | const field_index = @intCast(u32, field_ptr.field_index); |
| 19300 | | const field_ty = parent.ty.structFieldType(field_index); |
| 19301 | 19300 | switch (parent.val.tag()) { |
| 19302 | 19301 | .undef => { |
| 19303 | 19302 | // A struct or union has been initialized to undefined at comptime and now we |
| ... | ... | @@ -19316,7 +19315,7 @@ fn beginComptimePtrMutation( |
| 19316 | 19315 | return ComptimePtrMutationKit{ |
| 19317 | 19316 | .decl_ref_mut = parent.decl_ref_mut, |
| 19318 | 19317 | .val = &fields[field_index], |
| 19319 | | .ty = field_ty, |
| 19318 | .ty = parent.ty.structFieldType(field_index), |
| 19320 | 19319 | }; |
| 19321 | 19320 | }, |
| 19322 | 19321 | .Union => { |
| ... | ... | @@ -19331,16 +19330,37 @@ fn beginComptimePtrMutation( |
| 19331 | 19330 | return ComptimePtrMutationKit{ |
| 19332 | 19331 | .decl_ref_mut = parent.decl_ref_mut, |
| 19333 | 19332 | .val = &payload.data.val, |
| 19334 | | .ty = field_ty, |
| 19333 | .ty = parent.ty.structFieldType(field_index), |
| 19335 | 19334 | }; |
| 19336 | 19335 | }, |
| 19336 | .Pointer => { |
| 19337 | assert(parent.ty.isSlice()); |
| 19338 | parent.val.* = try Value.Tag.slice.create(arena, .{ |
| 19339 | .ptr = Value.undef, |
| 19340 | .len = Value.undef, |
| 19341 | }); |
| 19342 | |
| 19343 | switch (field_index) { |
| 19344 | Value.Payload.Slice.ptr_index => return ComptimePtrMutationKit{ |
| 19345 | .decl_ref_mut = parent.decl_ref_mut, |
| 19346 | .val = &parent.val.castTag(.slice).?.data.ptr, |
| 19347 | .ty = parent.ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer)), |
| 19348 | }, |
| 19349 | Value.Payload.Slice.len_index => return ComptimePtrMutationKit{ |
| 19350 | .decl_ref_mut = parent.decl_ref_mut, |
| 19351 | .val = &parent.val.castTag(.slice).?.data.len, |
| 19352 | .ty = Type.usize, |
| 19353 | }, |
| 19354 | else => unreachable, |
| 19355 | } |
| 19356 | }, |
| 19337 | 19357 | else => unreachable, |
| 19338 | 19358 | } |
| 19339 | 19359 | }, |
| 19340 | 19360 | .aggregate => return ComptimePtrMutationKit{ |
| 19341 | 19361 | .decl_ref_mut = parent.decl_ref_mut, |
| 19342 | 19362 | .val = &parent.val.castTag(.aggregate).?.data[field_index], |
| 19343 | | .ty = field_ty, |
| 19363 | .ty = parent.ty.structFieldType(field_index), |
| 19344 | 19364 | }, |
| 19345 | 19365 | .@"union" => { |
| 19346 | 19366 | // We need to set the active field of the union. |
| ... | ... | @@ -19353,9 +19373,22 @@ fn beginComptimePtrMutation( |
| 19353 | 19373 | return ComptimePtrMutationKit{ |
| 19354 | 19374 | .decl_ref_mut = parent.decl_ref_mut, |
| 19355 | 19375 | .val = &payload.val, |
| 19356 | | .ty = field_ty, |
| 19376 | .ty = parent.ty.structFieldType(field_index), |
| 19357 | 19377 | }; |
| 19358 | 19378 | }, |
| 19379 | .slice => switch (field_index) { |
| 19380 | Value.Payload.Slice.ptr_index => return ComptimePtrMutationKit{ |
| 19381 | .decl_ref_mut = parent.decl_ref_mut, |
| 19382 | .val = &parent.val.castTag(.slice).?.data.ptr, |
| 19383 | .ty = parent.ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer)), |
| 19384 | }, |
| 19385 | Value.Payload.Slice.len_index => return ComptimePtrMutationKit{ |
| 19386 | .decl_ref_mut = parent.decl_ref_mut, |
| 19387 | .val = &parent.val.castTag(.slice).?.data.len, |
| 19388 | .ty = Type.usize, |
| 19389 | }, |
| 19390 | else => unreachable, |
| 19391 | }, |
| 19359 | 19392 | |
| 19360 | 19393 | else => unreachable, |
| 19361 | 19394 | } |
| ... | ... | @@ -19555,7 +19588,6 @@ fn beginComptimePtrLoad( |
| 19555 | 19588 | .field_ptr => blk: { |
| 19556 | 19589 | const field_ptr = ptr_val.castTag(.field_ptr).?.data; |
| 19557 | 19590 | const field_index = @intCast(u32, field_ptr.field_index); |
| 19558 | | const field_ty = field_ptr.container_ty.structFieldType(field_index); |
| 19559 | 19591 | var deref = try beginComptimePtrLoad(sema, block, src, field_ptr.container_ptr, field_ptr.container_ty); |
| 19560 | 19592 | |
| 19561 | 19593 | if (field_ptr.container_ty.hasWellDefinedLayout()) { |
| ... | ... | @@ -19570,19 +19602,38 @@ fn beginComptimePtrLoad( |
| 19570 | 19602 | deref.ty_without_well_defined_layout = field_ptr.container_ty; |
| 19571 | 19603 | } |
| 19572 | 19604 | |
| 19573 | | if (deref.pointee) |*tv| { |
| 19574 | | const coerce_in_mem_ok = |
| 19575 | | (try sema.coerceInMemoryAllowed(block, field_ptr.container_ty, tv.ty, false, target, src, src)) == .ok or |
| 19576 | | (try sema.coerceInMemoryAllowed(block, tv.ty, field_ptr.container_ty, false, target, src, src)) == .ok; |
| 19577 | | if (coerce_in_mem_ok) { |
| 19578 | | deref.pointee = TypedValue{ |
| 19579 | | .ty = field_ty, |
| 19580 | | .val = tv.val.fieldValue(tv.ty, field_index), |
| 19581 | | }; |
| 19582 | | break :blk deref; |
| 19583 | | } |
| 19605 | const tv = &(deref.pointee orelse { |
| 19606 | deref.pointee = null; |
| 19607 | break :blk deref; |
| 19608 | }); |
| 19609 | const coerce_in_mem_ok = |
| 19610 | (try sema.coerceInMemoryAllowed(block, field_ptr.container_ty, tv.ty, false, target, src, src)) == .ok or |
| 19611 | (try sema.coerceInMemoryAllowed(block, tv.ty, field_ptr.container_ty, false, target, src, src)) == .ok; |
| 19612 | if (!coerce_in_mem_ok) { |
| 19613 | deref.pointee = null; |
| 19614 | break :blk deref; |
| 19615 | } |
| 19616 | |
| 19617 | if (field_ptr.container_ty.isSlice()) { |
| 19618 | const slice_val = tv.val.castTag(.slice).?.data; |
| 19619 | deref.pointee = switch (field_index) { |
| 19620 | Value.Payload.Slice.ptr_index => TypedValue{ |
| 19621 | .ty = field_ptr.container_ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer)), |
| 19622 | .val = slice_val.ptr, |
| 19623 | }, |
| 19624 | Value.Payload.Slice.len_index => TypedValue{ |
| 19625 | .ty = Type.usize, |
| 19626 | .val = slice_val.len, |
| 19627 | }, |
| 19628 | else => unreachable, |
| 19629 | }; |
| 19630 | } else { |
| 19631 | const field_ty = field_ptr.container_ty.structFieldType(field_index); |
| 19632 | deref.pointee = TypedValue{ |
| 19633 | .ty = field_ty, |
| 19634 | .val = tv.val.fieldValue(tv.ty, field_index), |
| 19635 | }; |
| 19584 | 19636 | } |
| 19585 | | deref.pointee = null; |
| 19586 | 19637 | break :blk deref; |
| 19587 | 19638 | }, |
| 19588 | 19639 | |