diff --git a/src/Sema.zig b/src/Sema.zig index 4a69c5b895..3df23ca2df 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -10388,25 +10388,32 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai )).?; try sema.mod.declareDeclDependency(sema.owner_decl, fn_info_decl); try sema.ensureDeclAnalyzed(fn_info_decl); + var fn_ty_buffer: Value.ToTypeBuffer = undefined; + const fn_ty = fn_info_decl.val.toType(&fn_ty_buffer); const param_info_decl = (try sema.namespaceLookup( block, src, - fn_info_decl.val.castTag(.ty).?.data.getNamespace().?, + fn_ty.getNamespace().?, "Param", )).?; try sema.mod.declareDeclDependency(sema.owner_decl, param_info_decl); try sema.ensureDeclAnalyzed(param_info_decl); + var param_buffer: Value.ToTypeBuffer = undefined; + const param_ty = param_info_decl.val.toType(¶m_buffer); const new_decl = try params_anon_decl.finish( try Type.Tag.array.create(params_anon_decl.arena(), .{ .len = param_vals.len, - .elem_type = param_info_decl.ty, + .elem_type = try param_ty.copy(params_anon_decl.arena()), }), try Value.Tag.aggregate.create( params_anon_decl.arena(), param_vals, ), ); - break :v try Value.Tag.decl_ref.create(sema.arena, new_decl); + break :v try Value.Tag.slice.create(sema.arena, .{ + .ptr = try Value.Tag.decl_ref.create(sema.arena, new_decl), + .len = try Value.Tag.int_u64.create(sema.arena, param_vals.len), + }); }; const ret_ty_opt = if (info.return_type.tag() != .generic_poison) @@ -10823,7 +10830,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai try fields_anon_decl.arena().dupe(Value, union_field_vals), ), ); - break :v try Value.Tag.decl_ref.create(sema.arena, new_decl); + break :v try Value.Tag.slice.create(sema.arena, .{ + .ptr = try Value.Tag.decl_ref.create(sema.arena, new_decl), + .len = try Value.Tag.int_u64.create(sema.arena, union_field_vals.len), + }); }; const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, union_ty.getNamespace()); @@ -10897,7 +10907,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len), try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), ); - break :v try Value.Tag.decl_ref.create(fields_anon_decl.arena(), new_decl); + break :v try Value.Tag.slice.create(sema.arena, .{ + .ptr = try Value.Tag.decl_ref.create(fields_anon_decl.arena(), new_decl), + .len = try Value.Tag.int_u64.create(sema.arena, bytes.len), + }); }; const struct_field_fields = try fields_anon_decl.arena().create([5]Value); @@ -10937,7 +10950,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len), try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), ); - break :v try Value.Tag.decl_ref.create(fields_anon_decl.arena(), new_decl); + break :v try Value.Tag.slice.create(sema.arena, .{ + .ptr = try Value.Tag.decl_ref.create(fields_anon_decl.arena(), new_decl), + .len = try Value.Tag.int_u64.create(sema.arena, bytes.len), + }); }; const struct_field_fields = try fields_anon_decl.arena().create([5]Value); @@ -10979,7 +10995,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai try fields_anon_decl.arena().dupe(Value, struct_field_vals), ), ); - break :v try Value.Tag.decl_ref.create(sema.arena, new_decl); + break :v try Value.Tag.slice.create(sema.arena, .{ + .ptr = try Value.Tag.decl_ref.create(sema.arena, new_decl), + .len = try Value.Tag.int_u64.create(sema.arena, struct_field_vals.len), + }); }; const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, struct_ty.getNamespace()); @@ -11048,7 +11067,7 @@ fn typeInfoDecls( block, src, type_info_ty.getNamespace().?, - "EnumField", + "Declaration", )).?; try sema.mod.declareDeclDependency(sema.owner_decl, declaration_ty_decl); try sema.ensureDeclAnalyzed(declaration_ty_decl); @@ -11069,7 +11088,10 @@ fn typeInfoDecls( try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len), try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), ); - break :v try Value.Tag.decl_ref.create(decls_anon_decl.arena(), new_decl); + break :v try Value.Tag.slice.create(decls_anon_decl.arena(), .{ + .ptr = try Value.Tag.decl_ref.create(decls_anon_decl.arena(), new_decl), + .len = try Value.Tag.int_u64.create(decls_anon_decl.arena(), bytes.len), + }); }; const fields = try decls_anon_decl.arena().create([2]Value); @@ -11092,7 +11114,10 @@ fn typeInfoDecls( try decls_anon_decl.arena().dupe(Value, decls_vals), ), ); - return try Value.Tag.decl_ref.create(sema.arena, new_decl); + return try Value.Tag.slice.create(sema.arena, .{ + .ptr = try Value.Tag.decl_ref.create(sema.arena, new_decl), + .len = try Value.Tag.int_u64.create(sema.arena, decls_vals.len), + }); } fn zirTypeof(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { @@ -16574,8 +16599,20 @@ fn elemVal( const runtime_src = if (maybe_slice_val) |slice_val| rs: { const index_val = maybe_index_val orelse break :rs elem_index_src; const index = @intCast(usize, index_val.toUnsignedInt()); - const elem_val = try slice_val.elemValue(sema.arena, index); - return sema.addConstant(array_ty.elemType2(), elem_val); + + const elem_ty = array_ty.elemType2(); + + var payload: Value.Payload.ElemPtr = .{ .data = .{ + .array_ptr = slice_val.slicePtr(), + .elem_ty = elem_ty, + .index = index, + } }; + const elem_ptr_val = Value.initPayload(&payload.base); + + if (try sema.pointerDeref(block, array_src, elem_ptr_val, array_ty)) |elem_val| { + return sema.addConstant(elem_ty, elem_val); + } + break :rs array_src; } else array_src; try sema.requireRuntimeBlock(block, runtime_src); @@ -16589,8 +16626,19 @@ fn elemVal( const array_val = maybe_array_val orelse break :rs array_src; const index_val = maybe_index_val orelse break :rs elem_index_src; const index = @intCast(usize, index_val.toUnsignedInt()); - const elem_val = try array_val.elemValue(sema.arena, index); - return sema.addConstant(array_ty.elemType2(), elem_val); + const elem_ty = array_ty.elemType2(); + + var payload: Value.Payload.ElemPtr = .{ .data = .{ + .array_ptr = array_val, + .elem_ty = elem_ty, + .index = index, + } }; + const elem_ptr_val = Value.initPayload(&payload.base); + + if (try sema.pointerDeref(block, array_src, elem_ptr_val, array_ty)) |elem_val| { + return sema.addConstant(elem_ty, elem_val); + } + break :rs array_src; }; try sema.requireRuntimeBlock(block, runtime_src); @@ -16739,7 +16787,7 @@ fn elemPtrArray( const index_u64 = index_val.toUnsignedInt(); // @intCast here because it would have been impossible to construct a value that // required a larger index. - const elem_ptr = try array_ptr_val.elemPtrDirect(array_ptr_ty, sema.arena, @intCast(usize, index_u64)); + const elem_ptr = try array_ptr_val.elemPtr(array_ptr_ty, sema.arena, @intCast(usize, index_u64)); return sema.addConstant(result_ty, elem_ptr); } } diff --git a/src/value.zig b/src/value.zig index 2ff196d491..d63452ee56 100644 --- a/src/value.zig +++ b/src/value.zig @@ -505,7 +505,6 @@ pub const Value = extern union { .array_ptr = try payload.data.array_ptr.copy(arena), .elem_ty = try payload.data.elem_ty.copy(arena), .index = payload.data.index, - .direct = payload.data.direct, }, }; return Value{ .ptr_otherwise = &new_payload.base }; @@ -2403,11 +2402,7 @@ pub const Value = extern union { .decl_ref_mut => return val.castTag(.decl_ref_mut).?.data.decl.val.elemValueAdvanced(index, arena, buffer), .elem_ptr => { const data = val.castTag(.elem_ptr).?.data; - if (!data.direct) - return data.array_ptr.elemValueAdvanced(index + data.index, arena, buffer); - - const underlying = try data.array_ptr.elemValueAdvanced(data.index, arena, buffer); - return underlying.elemValueAdvanced(index, arena, buffer); + return data.array_ptr.elemValueAdvanced(index + data.index, arena, buffer); }, // The child type of arrays which have only one possible value need @@ -2470,25 +2465,12 @@ pub const Value = extern union { /// Returns a pointer to the element value at the index. pub fn elemPtr(val: Value, ty: Type, arena: Allocator, index: usize) Allocator.Error!Value { - return val.elemPtrAdvanced(ty, arena, index, false); - } - - /// Returns a pointer to the element value at the index. The behavior - /// of this is slightly different for comptime; the "direct" means that - /// indexing indexes the referenced child value, not the parent array. - pub fn elemPtrDirect(val: Value, ty: Type, arena: Allocator, index: usize) Allocator.Error!Value { - return val.elemPtrAdvanced(ty, arena, index, true); - } - - pub fn elemPtrAdvanced(val: Value, ty: Type, arena: Allocator, index: usize, direct: bool) Allocator.Error!Value { const elem_ty = ty.elemType2(); const ptr_val = switch (val.tag()) { .slice => val.castTag(.slice).?.data.ptr, else => val, }; - // If the val is already an elem ptr, then we do ptr arithmetic logic - // and just move the index. if (ptr_val.tag() == .elem_ptr) { const elem_ptr = ptr_val.castTag(.elem_ptr).?.data; if (elem_ptr.elem_ty.eql(elem_ty)) { @@ -2496,12 +2478,6 @@ pub const Value = extern union { .array_ptr = elem_ptr.array_ptr, .elem_ty = elem_ptr.elem_ty, .index = elem_ptr.index + index, - - // Retain the direct preference. This enables a direct - // elem ptr (i.e. &arr[0]) to be bitcasted to a many-pointer - // with pointer arithmetic then casted back to a single - // pointer. - .direct = elem_ptr.direct, }); } } @@ -2509,7 +2485,6 @@ pub const Value = extern union { .array_ptr = ptr_val, .elem_ty = elem_ty, .index = index, - .direct = direct, }); } @@ -4219,7 +4194,6 @@ pub const Value = extern union { array_ptr: Value, elem_ty: Type, index: usize, - direct: bool, }, };