Commit cdeb1fb881
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);
}
}
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,
},
};