@typeInfo now uses optional types instead of @typeOf(undefined)
This commit is contained in:
parent
1ca90b5856
commit
1392313236
|
@ -5684,20 +5684,20 @@ pub const TypeInfo = union(TypeId) {
|
||||||
pub const FnArg = struct {
|
pub const FnArg = struct {
|
||||||
is_generic: bool,
|
is_generic: bool,
|
||||||
is_noalias: bool,
|
is_noalias: bool,
|
||||||
arg_type: type,
|
arg_type: ?type,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Fn = struct {
|
pub const Fn = struct {
|
||||||
calling_convention: CallingConvention,
|
calling_convention: CallingConvention,
|
||||||
is_generic: bool,
|
is_generic: bool,
|
||||||
is_var_args: bool,
|
is_var_args: bool,
|
||||||
return_type: type,
|
return_type: ?type,
|
||||||
async_allocator_type: type,
|
async_allocator_type: ?type,
|
||||||
args: []FnArg,
|
args: []FnArg,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Promise = struct {
|
pub const Promise = struct {
|
||||||
child: type,
|
child: ?type,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Definition = struct {
|
pub const Definition = struct {
|
||||||
|
|
|
@ -6627,7 +6627,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
|
||||||
"\n"
|
"\n"
|
||||||
" pub const Union = struct {\n"
|
" pub const Union = struct {\n"
|
||||||
" layout: ContainerLayout,\n"
|
" layout: ContainerLayout,\n"
|
||||||
" tag_type: type,\n"
|
" tag_type: ?type,\n"
|
||||||
" fields: []UnionField,\n"
|
" fields: []UnionField,\n"
|
||||||
" defs: []Definition,\n"
|
" defs: []Definition,\n"
|
||||||
" };\n"
|
" };\n"
|
||||||
|
@ -6644,20 +6644,20 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
|
||||||
" pub const FnArg = struct {\n"
|
" pub const FnArg = struct {\n"
|
||||||
" is_generic: bool,\n"
|
" is_generic: bool,\n"
|
||||||
" is_noalias: bool,\n"
|
" is_noalias: bool,\n"
|
||||||
" arg_type: type,\n"
|
" arg_type: ?type,\n"
|
||||||
" };\n"
|
" };\n"
|
||||||
"\n"
|
"\n"
|
||||||
" pub const Fn = struct {\n"
|
" pub const Fn = struct {\n"
|
||||||
" calling_convention: CallingConvention,\n"
|
" calling_convention: CallingConvention,\n"
|
||||||
" is_generic: bool,\n"
|
" is_generic: bool,\n"
|
||||||
" is_var_args: bool,\n"
|
" is_var_args: bool,\n"
|
||||||
" return_type: type,\n"
|
" return_type: ?type,\n"
|
||||||
" async_allocator_type: type,\n"
|
" async_allocator_type: ?type,\n"
|
||||||
" args: []FnArg,\n"
|
" args: []FnArg,\n"
|
||||||
" };\n"
|
" };\n"
|
||||||
"\n"
|
"\n"
|
||||||
" pub const Promise = struct {\n"
|
" pub const Promise = struct {\n"
|
||||||
" child: type,\n"
|
" child: ?type,\n"
|
||||||
" };\n"
|
" };\n"
|
||||||
"\n"
|
"\n"
|
||||||
" pub const Definition = struct {\n"
|
" pub const Definition = struct {\n"
|
||||||
|
|
75
src/ir.cpp
75
src/ir.cpp
|
@ -16722,16 +16722,20 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
|
||||||
ConstExprValue *fields = create_const_vals(1);
|
ConstExprValue *fields = create_const_vals(1);
|
||||||
result->data.x_struct.fields = fields;
|
result->data.x_struct.fields = fields;
|
||||||
|
|
||||||
// @TODO ?type instead of using @typeOf(undefined) when we have no type.
|
// child: ?type
|
||||||
// child: type
|
|
||||||
ensure_field_index(result->type, "child", 0);
|
ensure_field_index(result->type, "child", 0);
|
||||||
fields[0].special = ConstValSpecialStatic;
|
fields[0].special = ConstValSpecialStatic;
|
||||||
fields[0].type = ira->codegen->builtin_types.entry_type;
|
fields[0].type = get_maybe_type(ira->codegen, ira->codegen->builtin_types.entry_type);
|
||||||
|
|
||||||
if (type_entry->data.promise.result_type == nullptr)
|
if (type_entry->data.promise.result_type == nullptr)
|
||||||
fields[0].data.x_type = ira->codegen->builtin_types.entry_undef;
|
fields[0].data.x_optional = nullptr;
|
||||||
else
|
else {
|
||||||
fields[0].data.x_type = type_entry->data.promise.result_type;
|
ConstExprValue *child_type = create_const_vals(1);
|
||||||
|
child_type->special = ConstValSpecialStatic;
|
||||||
|
child_type->type = ira->codegen->builtin_types.entry_type;
|
||||||
|
child_type->data.x_type = type_entry->data.promise.result_type;
|
||||||
|
fields[0].data.x_optional = child_type;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -16872,19 +16876,23 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
|
||||||
fields[0].special = ConstValSpecialStatic;
|
fields[0].special = ConstValSpecialStatic;
|
||||||
fields[0].type = ir_type_info_get_type(ira, "ContainerLayout");
|
fields[0].type = ir_type_info_get_type(ira, "ContainerLayout");
|
||||||
bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.unionation.layout);
|
bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.unionation.layout);
|
||||||
// tag_type: type
|
// tag_type: ?type
|
||||||
ensure_field_index(result->type, "tag_type", 1);
|
ensure_field_index(result->type, "tag_type", 1);
|
||||||
fields[1].special = ConstValSpecialStatic;
|
fields[1].special = ConstValSpecialStatic;
|
||||||
fields[1].type = ira->codegen->builtin_types.entry_type;
|
fields[1].type = get_maybe_type(ira->codegen, ira->codegen->builtin_types.entry_type);
|
||||||
// @TODO ?type instead of using @typeOf(undefined) when we have no type.
|
|
||||||
AstNode *union_decl_node = type_entry->data.unionation.decl_node;
|
AstNode *union_decl_node = type_entry->data.unionation.decl_node;
|
||||||
if (union_decl_node->data.container_decl.auto_enum ||
|
if (union_decl_node->data.container_decl.auto_enum ||
|
||||||
union_decl_node->data.container_decl.init_arg_expr != nullptr)
|
union_decl_node->data.container_decl.init_arg_expr != nullptr)
|
||||||
{
|
{
|
||||||
fields[1].data.x_type = type_entry->data.unionation.tag_type;
|
ConstExprValue *tag_type = create_const_vals(1);
|
||||||
|
tag_type->special = ConstValSpecialStatic;
|
||||||
|
tag_type->type = ira->codegen->builtin_types.entry_type;
|
||||||
|
tag_type->data.x_type = type_entry->data.unionation.tag_type;
|
||||||
|
fields[1].data.x_optional = tag_type;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fields[1].data.x_type = ira->codegen->builtin_types.entry_undef;
|
fields[1].data.x_optional = nullptr;
|
||||||
// fields: []TypeInfo.UnionField
|
// fields: []TypeInfo.UnionField
|
||||||
ensure_field_index(result->type, "fields", 2);
|
ensure_field_index(result->type, "fields", 2);
|
||||||
|
|
||||||
|
@ -16913,7 +16921,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
|
||||||
inner_fields[1].special = ConstValSpecialStatic;
|
inner_fields[1].special = ConstValSpecialStatic;
|
||||||
inner_fields[1].type = get_maybe_type(ira->codegen, type_info_enum_field_type);
|
inner_fields[1].type = get_maybe_type(ira->codegen, type_info_enum_field_type);
|
||||||
|
|
||||||
if (fields[1].data.x_type == ira->codegen->builtin_types.entry_undef) {
|
if (fields[1].data.x_optional == nullptr) {
|
||||||
inner_fields[1].data.x_optional = nullptr;
|
inner_fields[1].data.x_optional = nullptr;
|
||||||
} else {
|
} else {
|
||||||
inner_fields[1].data.x_optional = create_const_vals(1);
|
inner_fields[1].data.x_optional = create_const_vals(1);
|
||||||
|
@ -17022,8 +17030,6 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
|
||||||
ConstExprValue *fields = create_const_vals(6);
|
ConstExprValue *fields = create_const_vals(6);
|
||||||
result->data.x_struct.fields = fields;
|
result->data.x_struct.fields = fields;
|
||||||
|
|
||||||
// @TODO Fix type = undefined with ?type
|
|
||||||
|
|
||||||
// calling_convention: TypeInfo.CallingConvention
|
// calling_convention: TypeInfo.CallingConvention
|
||||||
ensure_field_index(result->type, "calling_convention", 0);
|
ensure_field_index(result->type, "calling_convention", 0);
|
||||||
fields[0].special = ConstValSpecialStatic;
|
fields[0].special = ConstValSpecialStatic;
|
||||||
|
@ -17041,22 +17047,32 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
|
||||||
fields[2].special = ConstValSpecialStatic;
|
fields[2].special = ConstValSpecialStatic;
|
||||||
fields[2].type = ira->codegen->builtin_types.entry_bool;
|
fields[2].type = ira->codegen->builtin_types.entry_bool;
|
||||||
fields[2].data.x_bool = type_entry->data.fn.fn_type_id.is_var_args;
|
fields[2].data.x_bool = type_entry->data.fn.fn_type_id.is_var_args;
|
||||||
// return_type: type
|
// return_type: ?type
|
||||||
ensure_field_index(result->type, "return_type", 3);
|
ensure_field_index(result->type, "return_type", 3);
|
||||||
fields[3].special = ConstValSpecialStatic;
|
fields[3].special = ConstValSpecialStatic;
|
||||||
fields[3].type = ira->codegen->builtin_types.entry_type;
|
fields[3].type = get_maybe_type(ira->codegen, ira->codegen->builtin_types.entry_type);
|
||||||
if (type_entry->data.fn.fn_type_id.return_type == nullptr)
|
if (type_entry->data.fn.fn_type_id.return_type == nullptr)
|
||||||
fields[3].data.x_type = ira->codegen->builtin_types.entry_undef;
|
fields[3].data.x_optional = nullptr;
|
||||||
else
|
else {
|
||||||
fields[3].data.x_type = type_entry->data.fn.fn_type_id.return_type;
|
ConstExprValue *return_type = create_const_vals(1);
|
||||||
|
return_type->special = ConstValSpecialStatic;
|
||||||
|
return_type->type = ira->codegen->builtin_types.entry_type;
|
||||||
|
return_type->data.x_type = type_entry->data.fn.fn_type_id.return_type;
|
||||||
|
fields[3].data.x_optional = return_type;
|
||||||
|
}
|
||||||
// async_allocator_type: type
|
// async_allocator_type: type
|
||||||
ensure_field_index(result->type, "async_allocator_type", 4);
|
ensure_field_index(result->type, "async_allocator_type", 4);
|
||||||
fields[4].special = ConstValSpecialStatic;
|
fields[4].special = ConstValSpecialStatic;
|
||||||
fields[4].type = ira->codegen->builtin_types.entry_type;
|
fields[4].type = get_maybe_type(ira->codegen, ira->codegen->builtin_types.entry_type);
|
||||||
if (type_entry->data.fn.fn_type_id.async_allocator_type == nullptr)
|
if (type_entry->data.fn.fn_type_id.async_allocator_type == nullptr)
|
||||||
fields[4].data.x_type = ira->codegen->builtin_types.entry_undef;
|
fields[4].data.x_optional = nullptr;
|
||||||
else
|
else {
|
||||||
fields[4].data.x_type = type_entry->data.fn.fn_type_id.async_allocator_type;
|
ConstExprValue *async_alloc_type = create_const_vals(1);
|
||||||
|
async_alloc_type->special = ConstValSpecialStatic;
|
||||||
|
async_alloc_type->type = ira->codegen->builtin_types.entry_type;
|
||||||
|
async_alloc_type->data.x_type = type_entry->data.fn.fn_type_id.async_allocator_type;
|
||||||
|
fields[4].data.x_optional = async_alloc_type;
|
||||||
|
}
|
||||||
// args: []TypeInfo.FnArg
|
// args: []TypeInfo.FnArg
|
||||||
TypeTableEntry *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg");
|
TypeTableEntry *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg");
|
||||||
size_t fn_arg_count = type_entry->data.fn.fn_type_id.param_count -
|
size_t fn_arg_count = type_entry->data.fn.fn_type_id.param_count -
|
||||||
|
@ -17090,12 +17106,17 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
|
||||||
inner_fields[1].type = ira->codegen->builtin_types.entry_bool;
|
inner_fields[1].type = ira->codegen->builtin_types.entry_bool;
|
||||||
inner_fields[1].data.x_bool = fn_param_info->is_noalias;
|
inner_fields[1].data.x_bool = fn_param_info->is_noalias;
|
||||||
inner_fields[2].special = ConstValSpecialStatic;
|
inner_fields[2].special = ConstValSpecialStatic;
|
||||||
inner_fields[2].type = ira->codegen->builtin_types.entry_type;
|
inner_fields[2].type = get_maybe_type(ira->codegen, ira->codegen->builtin_types.entry_type);
|
||||||
|
|
||||||
if (arg_is_generic)
|
if (arg_is_generic)
|
||||||
inner_fields[2].data.x_type = ira->codegen->builtin_types.entry_undef;
|
inner_fields[2].data.x_optional = nullptr;
|
||||||
else
|
else {
|
||||||
inner_fields[2].data.x_type = fn_param_info->type;
|
ConstExprValue *arg_type = create_const_vals(1);
|
||||||
|
arg_type->special = ConstValSpecialStatic;
|
||||||
|
arg_type->type = ira->codegen->builtin_types.entry_type;
|
||||||
|
arg_type->data.x_type = fn_param_info->type;
|
||||||
|
inner_fields[2].data.x_optional = arg_type;
|
||||||
|
}
|
||||||
|
|
||||||
fn_arg_val->data.x_struct.fields = inner_fields;
|
fn_arg_val->data.x_struct.fields = inner_fields;
|
||||||
fn_arg_val->data.x_struct.parent.id = ConstParentIdArray;
|
fn_arg_val->data.x_struct.parent.id = ConstParentIdArray;
|
||||||
|
|
|
@ -107,11 +107,11 @@ test "type info: promise info" {
|
||||||
fn testPromise() void {
|
fn testPromise() void {
|
||||||
const null_promise_info = @typeInfo(promise);
|
const null_promise_info = @typeInfo(promise);
|
||||||
assert(TypeId(null_promise_info) == TypeId.Promise);
|
assert(TypeId(null_promise_info) == TypeId.Promise);
|
||||||
assert(null_promise_info.Promise.child == @typeOf(undefined));
|
assert(null_promise_info.Promise.child == null);
|
||||||
|
|
||||||
const promise_info = @typeInfo(promise->usize);
|
const promise_info = @typeInfo(promise->usize);
|
||||||
assert(TypeId(promise_info) == TypeId.Promise);
|
assert(TypeId(promise_info) == TypeId.Promise);
|
||||||
assert(promise_info.Promise.child == usize);
|
assert(promise_info.Promise.child.? == usize);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "type info: error set, error union info" {
|
test "type info: error set, error union info" {
|
||||||
|
@ -165,7 +165,7 @@ fn testUnion() void {
|
||||||
const typeinfo_info = @typeInfo(TypeInfo);
|
const typeinfo_info = @typeInfo(TypeInfo);
|
||||||
assert(TypeId(typeinfo_info) == TypeId.Union);
|
assert(TypeId(typeinfo_info) == TypeId.Union);
|
||||||
assert(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);
|
assert(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);
|
||||||
assert(typeinfo_info.Union.tag_type == TypeId);
|
assert(typeinfo_info.Union.tag_type.? == TypeId);
|
||||||
assert(typeinfo_info.Union.fields.len == 25);
|
assert(typeinfo_info.Union.fields.len == 25);
|
||||||
assert(typeinfo_info.Union.fields[4].enum_field != null);
|
assert(typeinfo_info.Union.fields[4].enum_field != null);
|
||||||
assert(typeinfo_info.Union.fields[4].enum_field.?.value == 4);
|
assert(typeinfo_info.Union.fields[4].enum_field.?.value == 4);
|
||||||
|
@ -179,7 +179,7 @@ fn testUnion() void {
|
||||||
|
|
||||||
const notag_union_info = @typeInfo(TestNoTagUnion);
|
const notag_union_info = @typeInfo(TestNoTagUnion);
|
||||||
assert(TypeId(notag_union_info) == TypeId.Union);
|
assert(TypeId(notag_union_info) == TypeId.Union);
|
||||||
assert(notag_union_info.Union.tag_type == @typeOf(undefined));
|
assert(notag_union_info.Union.tag_type == null);
|
||||||
assert(notag_union_info.Union.layout == TypeInfo.ContainerLayout.Auto);
|
assert(notag_union_info.Union.layout == TypeInfo.ContainerLayout.Auto);
|
||||||
assert(notag_union_info.Union.fields.len == 2);
|
assert(notag_union_info.Union.fields.len == 2);
|
||||||
assert(notag_union_info.Union.fields[0].enum_field == null);
|
assert(notag_union_info.Union.fields[0].enum_field == null);
|
||||||
|
@ -191,7 +191,7 @@ fn testUnion() void {
|
||||||
|
|
||||||
const extern_union_info = @typeInfo(TestExternUnion);
|
const extern_union_info = @typeInfo(TestExternUnion);
|
||||||
assert(extern_union_info.Union.layout == TypeInfo.ContainerLayout.Extern);
|
assert(extern_union_info.Union.layout == TypeInfo.ContainerLayout.Extern);
|
||||||
assert(extern_union_info.Union.tag_type == @typeOf(undefined));
|
assert(extern_union_info.Union.tag_type == null);
|
||||||
assert(extern_union_info.Union.fields[0].enum_field == null);
|
assert(extern_union_info.Union.fields[0].enum_field == null);
|
||||||
assert(extern_union_info.Union.fields[0].field_type == *c_void);
|
assert(extern_union_info.Union.fields[0].field_type == *c_void);
|
||||||
}
|
}
|
||||||
|
@ -238,13 +238,13 @@ fn testFunction() void {
|
||||||
assert(fn_info.Fn.is_generic);
|
assert(fn_info.Fn.is_generic);
|
||||||
assert(fn_info.Fn.args.len == 2);
|
assert(fn_info.Fn.args.len == 2);
|
||||||
assert(fn_info.Fn.is_var_args);
|
assert(fn_info.Fn.is_var_args);
|
||||||
assert(fn_info.Fn.return_type == @typeOf(undefined));
|
assert(fn_info.Fn.return_type == null);
|
||||||
assert(fn_info.Fn.async_allocator_type == @typeOf(undefined));
|
assert(fn_info.Fn.async_allocator_type == null);
|
||||||
|
|
||||||
const test_instance: TestStruct = undefined;
|
const test_instance: TestStruct = undefined;
|
||||||
const bound_fn_info = @typeInfo(@typeOf(test_instance.foo));
|
const bound_fn_info = @typeInfo(@typeOf(test_instance.foo));
|
||||||
assert(TypeId(bound_fn_info) == TypeId.BoundFn);
|
assert(TypeId(bound_fn_info) == TypeId.BoundFn);
|
||||||
assert(bound_fn_info.BoundFn.args[0].arg_type == *const TestStruct);
|
assert(bound_fn_info.BoundFn.args[0].arg_type.? == *const TestStruct);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foo(comptime a: usize, b: bool, args: ...) usize {
|
fn foo(comptime a: usize, b: bool, args: ...) usize {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user