Skip to content

remove anytype fields from the language #10766

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 7 additions & 8 deletions lib/std/builtin.zig
Original file line number Diff line number Diff line change
Expand Up @@ -226,11 +226,10 @@ pub const TypeInfo = union(enum) {
child: type,
is_allowzero: bool,

/// This field is an optional type.
/// The type of the sentinel is the element type of the pointer, which is
/// the value of the `child` field in this struct. However there is no way
/// to refer to that type here, so we use `anytype`.
sentinel: anytype,
/// to refer to that type here, so we use pointer to `anyopaque`.
sentinel: ?*const anyopaque,

/// This data structure is used by the Zig language code generation and
/// therefore must be kept in sync with the compiler implementation.
Expand All @@ -248,11 +247,10 @@ pub const TypeInfo = union(enum) {
len: comptime_int,
child: type,

/// This field is an optional type.
/// The type of the sentinel is the element type of the array, which is
/// the value of the `child` field in this struct. However there is no way
/// to refer to that type here, so we use `anytype`.
sentinel: anytype,
/// to refer to that type here, so we use pointer to `anyopaque`.
sentinel: ?*const anyopaque,
};

/// This data structure is used by the Zig language code generation and
Expand All @@ -267,8 +265,9 @@ pub const TypeInfo = union(enum) {
/// therefore must be kept in sync with the compiler implementation.
pub const StructField = struct {
name: []const u8,
/// TODO rename to `type`
field_type: type,
default_value: anytype,
default_value: ?*const anyopaque,
is_comptime: bool,
alignment: comptime_int,
};
Expand Down Expand Up @@ -369,7 +368,7 @@ pub const TypeInfo = union(enum) {
/// This data structure is used by the Zig language code generation and
/// therefore must be kept in sync with the compiler implementation.
pub const Frame = struct {
function: anytype,
function: *const anyopaque,
};

/// This data structure is used by the Zig language code generation and
Expand Down
4 changes: 2 additions & 2 deletions lib/std/crypto/benchmark.zig
Original file line number Diff line number Diff line change
Expand Up @@ -297,8 +297,8 @@ pub fn benchmarkAes8(comptime Aes: anytype, comptime count: comptime_int) !u64 {
}

const CryptoPwhash = struct {
hashFn: anytype,
params: anytype,
hashFn: @compileError("anytype fields are removed from the language"),
params: @compileError("anytype fields are removed from the language"),
name: []const u8,
};
const bcrypt_params = crypto.pwhash.bcrypt.Params{ .rounds_log = 12 };
Expand Down
2 changes: 1 addition & 1 deletion lib/std/enums.zig
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub fn EnumFieldStruct(comptime E: type, comptime Data: type, comptime field_def
fields = fields ++ &[_]StructField{.{
.name = field.name,
.field_type = Data,
.default_value = field_default,
.default_value = if (field_default) |d| &d else null,
.is_comptime = false,
.alignment = if (@sizeOf(Data) > 0) @alignOf(Data) else 0,
}};
Expand Down
3 changes: 2 additions & 1 deletion lib/std/json.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1791,8 +1791,9 @@ fn parseInternal(
}
inline for (structInfo.fields) |field, i| {
if (!fields_seen[i]) {
if (field.default_value) |default| {
if (field.default_value) |default_ptr| {
if (!field.is_comptime) {
const default = @ptrCast(*const field.field_type, default_ptr).*;
@field(r, field.name) = default;
}
} else {
Expand Down
53 changes: 35 additions & 18 deletions lib/std/mem.zig
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,8 @@ pub fn zeroes(comptime T: type) T {
}
},
.Array => |info| {
if (info.sentinel) |sentinel| {
if (info.sentinel) |sentinel_ptr| {
const sentinel = @ptrCast(*const info.child, sentinel_ptr).*;
return [_:sentinel]info.child{zeroes(info.child)} ** info.len;
}
return [_]info.child{zeroes(info.child)} ** info.len;
Expand Down Expand Up @@ -453,7 +454,8 @@ pub fn zeroInit(comptime T: type, init: anytype) T {
@field(value, field.name) = @field(init, field.name);
},
}
} else if (field.default_value) |default_value| {
} else if (field.default_value) |default_value_ptr| {
const default_value = @ptrCast(*const field.field_type, default_value_ptr).*;
@field(value, field.name) = default_value;
}
}
Expand Down Expand Up @@ -599,7 +601,7 @@ pub fn Span(comptime T: type) type {
else => @compileError("invalid type given to std.mem.Span"),
},
.C => {
new_ptr_info.sentinel = 0;
new_ptr_info.sentinel = &@as(ptr_info.child, 0);
new_ptr_info.is_allowzero = false;
},
.Many, .Slice => {},
Expand Down Expand Up @@ -651,7 +653,9 @@ pub fn span(ptr: anytype) Span(@TypeOf(ptr)) {
}
const Result = Span(@TypeOf(ptr));
const l = len(ptr);
if (@typeInfo(Result).Pointer.sentinel) |s| {
const ptr_info = @typeInfo(Result).Pointer;
if (ptr_info.sentinel) |s_ptr| {
const s = @ptrCast(*const ptr_info.child, s_ptr).*;
return ptr[0..l :s];
} else {
return ptr[0..l];
Expand Down Expand Up @@ -684,9 +688,10 @@ fn SliceTo(comptime T: type, comptime end: meta.Elem(T)) type {
// The return type must only be sentinel terminated if we are guaranteed
// to find the value searched for, which is only the case if it matches
// the sentinel of the type passed.
if (array_info.sentinel) |sentinel| {
if (array_info.sentinel) |sentinel_ptr| {
const sentinel = @ptrCast(*const array_info.child, sentinel_ptr).*;
if (end == sentinel) {
new_ptr_info.sentinel = end;
new_ptr_info.sentinel = &end;
} else {
new_ptr_info.sentinel = null;
}
Expand All @@ -698,16 +703,17 @@ fn SliceTo(comptime T: type, comptime end: meta.Elem(T)) type {
// The return type must only be sentinel terminated if we are guaranteed
// to find the value searched for, which is only the case if it matches
// the sentinel of the type passed.
if (ptr_info.sentinel) |sentinel| {
if (ptr_info.sentinel) |sentinel_ptr| {
const sentinel = @ptrCast(*const ptr_info.child, sentinel_ptr).*;
if (end == sentinel) {
new_ptr_info.sentinel = end;
new_ptr_info.sentinel = &end;
} else {
new_ptr_info.sentinel = null;
}
}
},
.C => {
new_ptr_info.sentinel = end;
new_ptr_info.sentinel = &end;
// C pointers are always allowzero, but we don't want the return type to be.
assert(new_ptr_info.is_allowzero);
new_ptr_info.is_allowzero = false;
Expand All @@ -734,7 +740,9 @@ pub fn sliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) SliceTo(@Typ
}
const Result = SliceTo(@TypeOf(ptr), end);
const length = lenSliceTo(ptr, end);
if (@typeInfo(Result).Pointer.sentinel) |s| {
const ptr_info = @typeInfo(Result).Pointer;
if (ptr_info.sentinel) |s_ptr| {
const s = @ptrCast(*const ptr_info.child, s_ptr).*;
return ptr[0..length :s];
} else {
return ptr[0..length];
Expand Down Expand Up @@ -786,7 +794,8 @@ fn lenSliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) usize {
.Pointer => |ptr_info| switch (ptr_info.size) {
.One => switch (@typeInfo(ptr_info.child)) {
.Array => |array_info| {
if (array_info.sentinel) |sentinel| {
if (array_info.sentinel) |sentinel_ptr| {
const sentinel = @ptrCast(*const array_info.child, sentinel_ptr).*;
if (sentinel == end) {
return indexOfSentinel(array_info.child, end, ptr);
}
Expand All @@ -795,7 +804,8 @@ fn lenSliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) usize {
},
else => {},
},
.Many => if (ptr_info.sentinel) |sentinel| {
.Many => if (ptr_info.sentinel) |sentinel_ptr| {
const sentinel = @ptrCast(*const ptr_info.child, sentinel_ptr).*;
// We may be looking for something other than the sentinel,
// but iterating past the sentinel would be a bug so we need
// to check for both.
Expand All @@ -808,7 +818,8 @@ fn lenSliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) usize {
return indexOfSentinel(ptr_info.child, end, ptr);
},
.Slice => {
if (ptr_info.sentinel) |sentinel| {
if (ptr_info.sentinel) |sentinel_ptr| {
const sentinel = @ptrCast(*const ptr_info.child, sentinel_ptr).*;
if (sentinel == end) {
return indexOfSentinel(ptr_info.child, sentinel, ptr);
}
Expand Down Expand Up @@ -867,10 +878,12 @@ pub fn len(value: anytype) usize {
.Array => value.len,
else => @compileError("invalid type given to std.mem.len"),
},
.Many => if (info.sentinel) |sentinel|
indexOfSentinel(info.child, sentinel, value)
else
@compileError("length of pointer with no sentinel"),
.Many => {
const sentinel_ptr = info.sentinel orelse
@compileError("length of pointer with no sentinel");
const sentinel = @ptrCast(*const info.child, sentinel_ptr).*;
return indexOfSentinel(info.child, sentinel, value);
},
.C => {
assert(value != null);
return indexOfSentinel(info.child, 0, value);
Expand Down Expand Up @@ -2572,7 +2585,11 @@ test "alignPointer" {
try S.checkAlign([*]u32, math.maxInt(usize) - 3, 8, 0);
}

fn CopyPtrAttrs(comptime source: type, comptime size: std.builtin.TypeInfo.Pointer.Size, comptime child: type) type {
fn CopyPtrAttrs(
comptime source: type,
comptime size: std.builtin.TypeInfo.Pointer.Size,
comptime child: type,
) type {
const info = @typeInfo(source).Pointer;
return @Type(.{
.Pointer = .{
Expand Down
21 changes: 15 additions & 6 deletions lib/std/meta.zig
Original file line number Diff line number Diff line change
Expand Up @@ -190,12 +190,21 @@ test "std.meta.Elem" {
/// Types which cannot possibly have a sentinel will be a compile error.
pub fn sentinel(comptime T: type) ?Elem(T) {
switch (@typeInfo(T)) {
.Array => |info| return info.sentinel,
.Array => |info| {
const sentinel_ptr = info.sentinel orelse return null;
return @ptrCast(*const info.child, sentinel_ptr).*;
},
.Pointer => |info| {
switch (info.size) {
.Many, .Slice => return info.sentinel,
.Many, .Slice => {
const sentinel_ptr = info.sentinel orelse return null;
return @ptrCast(*const info.child, sentinel_ptr).*;
},
.One => switch (@typeInfo(info.child)) {
.Array => |array_info| return array_info.sentinel,
.Array => |array_info| {
const sentinel_ptr = array_info.sentinel orelse return null;
return @ptrCast(*const array_info.child, sentinel_ptr).*;
},
else => {},
},
else => {},
Expand Down Expand Up @@ -239,7 +248,7 @@ pub fn Sentinel(comptime T: type, comptime sentinel_val: Elem(T)) type {
.Array = .{
.len = array_info.len,
.child = array_info.child,
.sentinel = sentinel_val,
.sentinel = &sentinel_val,
},
}),
.is_allowzero = info.is_allowzero,
Expand All @@ -257,7 +266,7 @@ pub fn Sentinel(comptime T: type, comptime sentinel_val: Elem(T)) type {
.address_space = info.address_space,
.child = info.child,
.is_allowzero = info.is_allowzero,
.sentinel = sentinel_val,
.sentinel = &sentinel_val,
},
}),
else => {},
Expand All @@ -275,7 +284,7 @@ pub fn Sentinel(comptime T: type, comptime sentinel_val: Elem(T)) type {
.address_space = ptr_info.address_space,
.child = ptr_info.child,
.is_allowzero = ptr_info.is_allowzero,
.sentinel = sentinel_val,
.sentinel = &sentinel_val,
},
}),
},
Expand Down
5 changes: 0 additions & 5 deletions lib/std/zig/Ast.zig
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,6 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex {
.builtin_call,
.builtin_call_comma,
.error_set_decl,
.@"anytype",
.@"comptime",
.@"nosuspend",
.asm_simple,
Expand Down Expand Up @@ -729,7 +728,6 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex {
.error_value,
=> return datas[n].rhs + end_offset,

.@"anytype",
.anyframe_literal,
.char_literal,
.integer_literal,
Expand Down Expand Up @@ -2935,9 +2933,6 @@ pub const Node = struct {
/// main_token is the field name identifier.
/// lastToken() does not include the possible trailing comma.
container_field,
/// `anytype`. both lhs and rhs unused.
/// Used by `ContainerField`.
@"anytype",
/// `comptime lhs`. rhs unused.
@"comptime",
/// `nosuspend lhs`. rhs unused.
Expand Down
15 changes: 2 additions & 13 deletions lib/std/zig/parse.zig
Original file line number Diff line number Diff line change
Expand Up @@ -786,19 +786,8 @@ const Parser = struct {
var align_expr: Node.Index = 0;
var type_expr: Node.Index = 0;
if (p.eatToken(.colon)) |_| {
if (p.eatToken(.keyword_anytype)) |anytype_tok| {
type_expr = try p.addNode(.{
.tag = .@"anytype",
.main_token = anytype_tok,
.data = .{
.lhs = undefined,
.rhs = undefined,
},
});
} else {
type_expr = try p.expectTypeExpr();
align_expr = try p.parseByteAlign();
}
type_expr = try p.expectTypeExpr();
align_expr = try p.parseByteAlign();
}

const value_expr: Node.Index = if (p.eatToken(.equal) == null) 0 else try p.expectExpr();
Expand Down
2 changes: 0 additions & 2 deletions lib/std/zig/render.zig
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,6 @@ fn renderExpression(gpa: Allocator, ais: *Ais, tree: Ast, node: Ast.Node.Index,
return renderToken(ais, tree, main_tokens[node] + 2, space);
},

.@"anytype" => return renderToken(ais, tree, main_tokens[node], space),

.block_two,
.block_two_semicolon,
=> {
Expand Down
Loading