@typeInfo now uses optional types instead of @typeOf(undefined)

This commit is contained in:
Alexandros Naskos 2018-06-19 17:45:19 +03:00
parent 1ca90b5856
commit 1392313236
4 changed files with 65 additions and 44 deletions

View File

@ -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 {

View File

@ -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"

View File

@ -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;

View File

@ -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 {