Commit f9e7bd2682

tgschultz <tgschultz@gmail.com>
2019-05-26 23:22:45
std.meta/trait: def/definition => decl/declaration TypeInfo: defs/Definition => decls/Declarations
1 parent 01a4897
Changed files (7)
doc/langref.html.in
@@ -7545,7 +7545,7 @@ pub const TypeInfo = union(TypeId) {
     pub const Struct = struct {
         layout: ContainerLayout,
         fields: []StructField,
-        defs: []Definition,
+        decls: []Declaration,
     };
 
     pub const Optional = struct {
@@ -7573,7 +7573,7 @@ pub const TypeInfo = union(TypeId) {
         layout: ContainerLayout,
         tag_type: type,
         fields: []EnumField,
-        defs: []Definition,
+        decls: []Declaration,
     };
 
     pub const UnionField = struct {
@@ -7586,7 +7586,7 @@ pub const TypeInfo = union(TypeId) {
         layout: ContainerLayout,
         tag_type: ?type,
         fields: []UnionField,
-        defs: []Definition,
+        decls: []Declaration,
     };
 
     pub const CallingConvention = enum {
@@ -7622,7 +7622,7 @@ pub const TypeInfo = union(TypeId) {
         child: type,
     };
 
-    pub const Definition = struct {
+    pub const Declaration = struct {
         name: []const u8,
         is_pub: bool,
         data: Data,
@@ -7630,9 +7630,9 @@ pub const TypeInfo = union(TypeId) {
         pub const Data = union(enum) {
             Type: type,
             Var: type,
-            Fn: FnDef,
+            Fn: FnDecl,
 
-            pub const FnDef = struct {
+            pub const FnDecl = struct {
                 fn_type: type,
                 inline_type: Inline,
                 calling_convention: CallingConvention,
src/codegen.cpp
@@ -7762,7 +7762,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
             "    pub const Struct = struct {\n"
             "        layout: ContainerLayout,\n"
             "        fields: []StructField,\n"
-            "        defs: []Definition,\n"
+            "        decls: []Declaration,\n"
             "    };\n"
             "\n"
             "    pub const Optional = struct {\n"
@@ -7790,7 +7790,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
             "        layout: ContainerLayout,\n"
             "        tag_type: type,\n"
             "        fields: []EnumField,\n"
-            "        defs: []Definition,\n"
+            "        decls: []Declaration,\n"
             "    };\n"
             "\n"
             "    pub const UnionField = struct {\n"
@@ -7803,7 +7803,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
             "        layout: ContainerLayout,\n"
             "        tag_type: ?type,\n"
             "        fields: []UnionField,\n"
-            "        defs: []Definition,\n"
+            "        decls: []Declaration,\n"
             "    };\n"
             "\n"
             "    pub const CallingConvention = enum {\n"
@@ -7839,7 +7839,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
             "        child: type,\n"
             "    };\n"
             "\n"
-            "    pub const Definition = struct {\n"
+            "    pub const Declaration = struct {\n"
             "        name: []const u8,\n"
             "        is_pub: bool,\n"
             "        data: Data,\n"
@@ -7847,9 +7847,9 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
             "        pub const Data = union(enum) {\n"
             "            Type: type,\n"
             "            Var: type,\n"
-            "            Fn: FnDef,\n"
+            "            Fn: FnDecl,\n"
             "\n"
-            "            pub const FnDef = struct {\n"
+            "            pub const FnDecl = struct {\n"
             "                fn_type: type,\n"
             "                inline_type: Inline,\n"
             "                calling_convention: CallingConvention,\n"
src/ir.cpp
@@ -18380,37 +18380,37 @@ static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, Zig
     return var->const_value->data.x_type;
 }
 
-static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr, ConstExprValue *out_val,
+static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr, ConstExprValue *out_val,
         ScopeDecls *decls_scope)
 {
     Error err;
-    ZigType *type_info_definition_type = ir_type_info_get_type(ira, "Definition", nullptr);
-    if ((err = type_resolve(ira->codegen, type_info_definition_type, ResolveStatusSizeKnown)))
+    ZigType *type_info_declaration_type = ir_type_info_get_type(ira, "Declaration", nullptr);
+    if ((err = type_resolve(ira->codegen, type_info_declaration_type, ResolveStatusSizeKnown)))
         return err;
 
-    ensure_field_index(type_info_definition_type, "name", 0);
-    ensure_field_index(type_info_definition_type, "is_pub", 1);
-    ensure_field_index(type_info_definition_type, "data", 2);
+    ensure_field_index(type_info_declaration_type, "name", 0);
+    ensure_field_index(type_info_declaration_type, "is_pub", 1);
+    ensure_field_index(type_info_declaration_type, "data", 2);
 
-    ZigType *type_info_definition_data_type = ir_type_info_get_type(ira, "Data", type_info_definition_type);
-    if ((err = ensure_complete_type(ira->codegen, type_info_definition_data_type)))
+    ZigType *type_info_declaration_data_type = ir_type_info_get_type(ira, "Data", type_info_declaration_type);
+    if ((err = ensure_complete_type(ira->codegen, type_info_declaration_data_type)))
         return err;
 
-    ZigType *type_info_fn_def_type = ir_type_info_get_type(ira, "FnDef", type_info_definition_data_type);
-    if ((err = ensure_complete_type(ira->codegen, type_info_fn_def_type)))
+    ZigType *type_info_fn_decl_type = ir_type_info_get_type(ira, "FnDecl", type_info_declaration_data_type);
+    if ((err = ensure_complete_type(ira->codegen, type_info_fn_decl_type)))
         return err;
 
-    ZigType *type_info_fn_def_inline_type = ir_type_info_get_type(ira, "Inline", type_info_fn_def_type);
-    if ((err = ensure_complete_type(ira->codegen, type_info_fn_def_inline_type)))
+    ZigType *type_info_fn_decl_inline_type = ir_type_info_get_type(ira, "Inline", type_info_fn_decl_type);
+    if ((err = ensure_complete_type(ira->codegen, type_info_fn_decl_inline_type)))
         return err;
 
-    // Loop through our definitions once to figure out how many definitions we will generate info for.
+    // Loop through our declarations once to figure out how many declarations we will generate info for.
     auto decl_it = decls_scope->decl_table.entry_iterator();
     decltype(decls_scope->decl_table)::Entry *curr_entry = nullptr;
-    int definition_count = 0;
+    int declaration_count = 0;
 
     while ((curr_entry = decl_it.next()) != nullptr) {
-        // If the definition is unresolved, force it to be resolved again.
+        // If the declaration is unresolved, force it to be resolved again.
         if (curr_entry->value->resolution == TldResolutionUnresolved) {
             resolve_top_level_decl(ira->codegen, curr_entry->value, curr_entry->value->source_node);
             if (curr_entry->value->resolution != TldResolutionOk) {
@@ -18426,21 +18426,21 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,
                     continue;
             }
 
-            definition_count += 1;
+            declaration_count += 1;
         }
     }
 
-    ConstExprValue *definition_array = create_const_vals(1);
-    definition_array->special = ConstValSpecialStatic;
-    definition_array->type = get_array_type(ira->codegen, type_info_definition_type, definition_count);
-    definition_array->data.x_array.special = ConstArraySpecialNone;
-    definition_array->data.x_array.data.s_none.elements = create_const_vals(definition_count);
-    init_const_slice(ira->codegen, out_val, definition_array, 0, definition_count, false);
+    ConstExprValue *declaration_array = create_const_vals(1);
+    declaration_array->special = ConstValSpecialStatic;
+    declaration_array->type = get_array_type(ira->codegen, type_info_declaration_type, declaration_count);
+    declaration_array->data.x_array.special = ConstArraySpecialNone;
+    declaration_array->data.x_array.data.s_none.elements = create_const_vals(declaration_count);
+    init_const_slice(ira->codegen, out_val, declaration_array, 0, declaration_count, false);
 
-    // Loop through the definitions and generate info.
+    // Loop through the declarations and generate info.
     decl_it = decls_scope->decl_table.entry_iterator();
     curr_entry = nullptr;
-    int definition_index = 0;
+    int declaration_index = 0;
     while ((curr_entry = decl_it.next()) != nullptr) {
         // Skip comptime blocks and test functions.
         if (curr_entry->value->id == TldIdCompTime) {
@@ -18451,10 +18451,10 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,
                 continue;
         }
 
-        ConstExprValue *definition_val = &definition_array->data.x_array.data.s_none.elements[definition_index];
+        ConstExprValue *declaration_val = &declaration_array->data.x_array.data.s_none.elements[declaration_index];
 
-        definition_val->special = ConstValSpecialStatic;
-        definition_val->type = type_info_definition_type;
+        declaration_val->special = ConstValSpecialStatic;
+        declaration_val->type = type_info_declaration_type;
 
         ConstExprValue *inner_fields = create_const_vals(3);
         ConstExprValue *name = create_const_str_lit(ira->codegen, curr_entry->key);
@@ -18463,9 +18463,9 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,
         inner_fields[1].type = ira->codegen->builtin_types.entry_bool;
         inner_fields[1].data.x_bool = curr_entry->value->visib_mod == VisibModPub;
         inner_fields[2].special = ConstValSpecialStatic;
-        inner_fields[2].type = type_info_definition_data_type;
+        inner_fields[2].type = type_info_declaration_data_type;
         inner_fields[2].parent.id = ConstParentIdStruct;
-        inner_fields[2].parent.data.p_struct.struct_val = definition_val;
+        inner_fields[2].parent.data.p_struct.struct_val = declaration_val;
         inner_fields[2].parent.data.p_struct.field_index = 1;
 
         switch (curr_entry->value->id) {
@@ -18476,7 +18476,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,
                         return ErrorSemanticAnalyzeFail;
 
                     if (var->const_value->type->id == ZigTypeIdMetaType) {
-                        // We have a variable of type 'type', so it's actually a type definition.
+                        // We have a variable of type 'type', so it's actually a type declaration.
                         // 0: Data.Type: type
                         bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 0);
                         inner_fields[2].data.x_union.payload = var->const_value;
@@ -18496,7 +18496,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,
                 }
             case TldIdFn:
                 {
-                    // 2: Data.Fn: Data.FnDef
+                    // 2: Data.Fn: Data.FnDecl
                     bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 2);
 
                     ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry;
@@ -18509,68 +18509,68 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,
 
                     AstNodeFnProto *fn_node = &fn_entry->proto_node->data.fn_proto;
 
-                    ConstExprValue *fn_def_val = create_const_vals(1);
-                    fn_def_val->special = ConstValSpecialStatic;
-                    fn_def_val->type = type_info_fn_def_type;
-                    fn_def_val->parent.id = ConstParentIdUnion;
-                    fn_def_val->parent.data.p_union.union_val = &inner_fields[2];
+                    ConstExprValue *fn_decl_val = create_const_vals(1);
+                    fn_decl_val->special = ConstValSpecialStatic;
+                    fn_decl_val->type = type_info_fn_decl_type;
+                    fn_decl_val->parent.id = ConstParentIdUnion;
+                    fn_decl_val->parent.data.p_union.union_val = &inner_fields[2];
 
-                    ConstExprValue *fn_def_fields = create_const_vals(9);
-                    fn_def_val->data.x_struct.fields = fn_def_fields;
+                    ConstExprValue *fn_decl_fields = create_const_vals(9);
+                    fn_decl_val->data.x_struct.fields = fn_decl_fields;
 
                     // fn_type: type
-                    ensure_field_index(fn_def_val->type, "fn_type", 0);
-                    fn_def_fields[0].special = ConstValSpecialStatic;
-                    fn_def_fields[0].type = ira->codegen->builtin_types.entry_type;
-                    fn_def_fields[0].data.x_type = fn_entry->type_entry;
-                    // inline_type: Data.FnDef.Inline
-                    ensure_field_index(fn_def_val->type, "inline_type", 1);
-                    fn_def_fields[1].special = ConstValSpecialStatic;
-                    fn_def_fields[1].type = type_info_fn_def_inline_type;
-                    bigint_init_unsigned(&fn_def_fields[1].data.x_enum_tag, fn_entry->fn_inline);
+                    ensure_field_index(fn_decl_val->type, "fn_type", 0);
+                    fn_decl_fields[0].special = ConstValSpecialStatic;
+                    fn_decl_fields[0].type = ira->codegen->builtin_types.entry_type;
+                    fn_decl_fields[0].data.x_type = fn_entry->type_entry;
+                    // inline_type: Data.FnDecl.Inline
+                    ensure_field_index(fn_decl_val->type, "inline_type", 1);
+                    fn_decl_fields[1].special = ConstValSpecialStatic;
+                    fn_decl_fields[1].type = type_info_fn_decl_inline_type;
+                    bigint_init_unsigned(&fn_decl_fields[1].data.x_enum_tag, fn_entry->fn_inline);
                     // calling_convention: TypeInfo.CallingConvention
-                    ensure_field_index(fn_def_val->type, "calling_convention", 2);
-                    fn_def_fields[2].special = ConstValSpecialStatic;
-                    fn_def_fields[2].type = ir_type_info_get_type(ira, "CallingConvention", nullptr);
-                    bigint_init_unsigned(&fn_def_fields[2].data.x_enum_tag, fn_node->cc);
+                    ensure_field_index(fn_decl_val->type, "calling_convention", 2);
+                    fn_decl_fields[2].special = ConstValSpecialStatic;
+                    fn_decl_fields[2].type = ir_type_info_get_type(ira, "CallingConvention", nullptr);
+                    bigint_init_unsigned(&fn_decl_fields[2].data.x_enum_tag, fn_node->cc);
                     // is_var_args: bool
-                    ensure_field_index(fn_def_val->type, "is_var_args", 3);
+                    ensure_field_index(fn_decl_val->type, "is_var_args", 3);
                     bool is_varargs = fn_node->is_var_args;
-                    fn_def_fields[3].special = ConstValSpecialStatic;
-                    fn_def_fields[3].type = ira->codegen->builtin_types.entry_bool;
-                    fn_def_fields[3].data.x_bool = is_varargs;
+                    fn_decl_fields[3].special = ConstValSpecialStatic;
+                    fn_decl_fields[3].type = ira->codegen->builtin_types.entry_bool;
+                    fn_decl_fields[3].data.x_bool = is_varargs;
                     // is_extern: bool
-                    ensure_field_index(fn_def_val->type, "is_extern", 4);
-                    fn_def_fields[4].special = ConstValSpecialStatic;
-                    fn_def_fields[4].type = ira->codegen->builtin_types.entry_bool;
-                    fn_def_fields[4].data.x_bool = fn_node->is_extern;
+                    ensure_field_index(fn_decl_val->type, "is_extern", 4);
+                    fn_decl_fields[4].special = ConstValSpecialStatic;
+                    fn_decl_fields[4].type = ira->codegen->builtin_types.entry_bool;
+                    fn_decl_fields[4].data.x_bool = fn_node->is_extern;
                     // is_export: bool
-                    ensure_field_index(fn_def_val->type, "is_export", 5);
-                    fn_def_fields[5].special = ConstValSpecialStatic;
-                    fn_def_fields[5].type = ira->codegen->builtin_types.entry_bool;
-                    fn_def_fields[5].data.x_bool = fn_node->is_export;
+                    ensure_field_index(fn_decl_val->type, "is_export", 5);
+                    fn_decl_fields[5].special = ConstValSpecialStatic;
+                    fn_decl_fields[5].type = ira->codegen->builtin_types.entry_bool;
+                    fn_decl_fields[5].data.x_bool = fn_node->is_export;
                     // lib_name: ?[]const u8
-                    ensure_field_index(fn_def_val->type, "lib_name", 6);
-                    fn_def_fields[6].special = ConstValSpecialStatic;
+                    ensure_field_index(fn_decl_val->type, "lib_name", 6);
+                    fn_decl_fields[6].special = ConstValSpecialStatic;
                     ZigType *u8_ptr = get_pointer_to_type_extra(
                         ira->codegen, ira->codegen->builtin_types.entry_u8,
                         true, false, PtrLenUnknown,
                         0, 0, 0, false);
-                    fn_def_fields[6].type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr));
+                    fn_decl_fields[6].type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr));
                     if (fn_node->is_extern && buf_len(fn_node->lib_name) > 0) {
-                        fn_def_fields[6].data.x_optional = create_const_vals(1);
+                        fn_decl_fields[6].data.x_optional = create_const_vals(1);
                         ConstExprValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name);
-                        init_const_slice(ira->codegen, fn_def_fields[6].data.x_optional, lib_name, 0, buf_len(fn_node->lib_name), true);
+                        init_const_slice(ira->codegen, fn_decl_fields[6].data.x_optional, lib_name, 0, buf_len(fn_node->lib_name), true);
                     } else {
-                        fn_def_fields[6].data.x_optional = nullptr;
+                        fn_decl_fields[6].data.x_optional = nullptr;
                     }
                     // return_type: type
-                    ensure_field_index(fn_def_val->type, "return_type", 7);
-                    fn_def_fields[7].special = ConstValSpecialStatic;
-                    fn_def_fields[7].type = ira->codegen->builtin_types.entry_type;
-                    fn_def_fields[7].data.x_type = fn_entry->type_entry->data.fn.fn_type_id.return_type;
+                    ensure_field_index(fn_decl_val->type, "return_type", 7);
+                    fn_decl_fields[7].special = ConstValSpecialStatic;
+                    fn_decl_fields[7].type = ira->codegen->builtin_types.entry_type;
+                    fn_decl_fields[7].data.x_type = fn_entry->type_entry->data.fn.fn_type_id.return_type;
                     // arg_names: [][] const u8
-                    ensure_field_index(fn_def_val->type, "arg_names", 8);
+                    ensure_field_index(fn_decl_val->type, "arg_names", 8);
                     size_t fn_arg_count = fn_entry->variable_list.length;
                     ConstExprValue *fn_arg_name_array = create_const_vals(1);
                     fn_arg_name_array->special = ConstValSpecialStatic;
@@ -18579,7 +18579,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,
                     fn_arg_name_array->data.x_array.special = ConstArraySpecialNone;
                     fn_arg_name_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count);
 
-                    init_const_slice(ira->codegen, &fn_def_fields[8], fn_arg_name_array, 0, fn_arg_count, false);
+                    init_const_slice(ira->codegen, &fn_decl_fields[8], fn_arg_name_array, 0, fn_arg_count, false);
 
                     for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) {
                         ZigVar *arg_var = fn_entry->variable_list.at(fn_arg_index);
@@ -18591,7 +18591,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,
                         fn_arg_name_val->parent.data.p_array.elem_index = fn_arg_index;
                     }
 
-                    inner_fields[2].data.x_union.payload = fn_def_val;
+                    inner_fields[2].data.x_union.payload = fn_decl_val;
                     break;
                 }
             case TldIdContainer:
@@ -18615,11 +18615,11 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,
                 zig_unreachable();
         }
 
-        definition_val->data.x_struct.fields = inner_fields;
-        definition_index++;
+        declaration_val->data.x_struct.fields = inner_fields;
+        declaration_index++;
     }
 
-    assert(definition_index == definition_count);
+    assert(declaration_index == declaration_count);
     return ErrorNone;
 }
 
@@ -18927,9 +18927,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
                     enum_field_val->parent.data.p_array.array_val = enum_field_array;
                     enum_field_val->parent.data.p_array.elem_index = enum_field_index;
                 }
-                // defs: []TypeInfo.Definition
-                ensure_field_index(result->type, "defs", 3);
-                if ((err = ir_make_type_info_defs(ira, source_instr, &fields[3],
+                // decls: []TypeInfo.Declaration
+                ensure_field_index(result->type, "decls", 3);
+                if ((err = ir_make_type_info_decls(ira, source_instr, &fields[3],
                             type_entry->data.enumeration.decls_scope)))
                 {
                     return err;
@@ -19094,9 +19094,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
                     union_field_val->parent.data.p_array.array_val = union_field_array;
                     union_field_val->parent.data.p_array.elem_index = union_field_index;
                 }
-                // defs: []TypeInfo.Definition
-                ensure_field_index(result->type, "defs", 3);
-                if ((err = ir_make_type_info_defs(ira, source_instr, &fields[3],
+                // decls: []TypeInfo.Declaration
+                ensure_field_index(result->type, "decls", 3);
+                if ((err = ir_make_type_info_decls(ira, source_instr, &fields[3],
                                 type_entry->data.unionation.decls_scope)))
                 {
                     return err;
@@ -19175,9 +19175,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
                     struct_field_val->parent.data.p_array.array_val = struct_field_array;
                     struct_field_val->parent.data.p_array.elem_index = struct_field_index;
                 }
-                // defs: []TypeInfo.Definition
-                ensure_field_index(result->type, "defs", 2);
-                if ((err = ir_make_type_info_defs(ira, source_instr, &fields[2],
+                // decls: []TypeInfo.Declaration
+                ensure_field_index(result->type, "decls", 2);
+                if ((err = ir_make_type_info_decls(ira, source_instr, &fields[2],
                                 type_entry->data.structure.decls_scope)))
                 {
                     return err;
std/meta/trait.zig
@@ -55,53 +55,15 @@ test "std.meta.trait.multiTrait" {
     testing.expect(!isVector(u8));
 }
 
-///
-pub fn hasDef(comptime name: []const u8) TraitFn {
-    const Closure = struct {
-        pub fn trait(comptime T: type) bool {
-            const info = @typeInfo(T);
-            const defs = switch (info) {
-                builtin.TypeId.Struct => |s| s.defs,
-                builtin.TypeId.Union => |u| u.defs,
-                builtin.TypeId.Enum => |e| e.defs,
-                else => return false,
-            };
-
-            inline for (defs) |def| {
-                if (mem.eql(u8, def.name, name)) return def.is_pub;
-            }
-
-            return false;
-        }
-    };
-    return Closure.trait;
-}
-
-test "std.meta.trait.hasDef" {
-    const TestStruct = struct {
-        pub const value = u8(16);
-    };
-
-    const TestStructFail = struct {
-        const value = u8(16);
-    };
-
-    testing.expect(hasDef("value")(TestStruct));
-    testing.expect(!hasDef("value")(TestStructFail));
-    testing.expect(!hasDef("value")(*TestStruct));
-    testing.expect(!hasDef("value")(**TestStructFail));
-    testing.expect(!hasDef("x")(TestStruct));
-    testing.expect(!hasDef("value")(u8));
-}
-
 ///
 pub fn hasFn(comptime name: []const u8) TraitFn {
     const Closure = struct {
         pub fn trait(comptime T: type) bool {
-            if (!comptime hasDef(name)(T)) return false;
-            const DefType = @typeOf(@field(T, name));
-            const def_type_id = @typeId(DefType);
-            return def_type_id == builtin.TypeId.Fn;
+            if (!comptime isContainer(T)) return false;
+            if (!comptime @hasDecl(T, name)) return false;
+            const DeclType = @typeOf(@field(T, name));
+            const decl_type_id = @typeId(DeclType);
+            return decl_type_id == builtin.TypeId.Fn;
         }
     };
     return Closure.trait;
std/fmt.zig
@@ -145,23 +145,7 @@ pub fn formatType(
             return format(context, Errors, output, "promise@{x}", @ptrToInt(value));
         },
         builtin.TypeId.Enum, builtin.TypeId.Union, builtin.TypeId.Struct => {
-            const has_cust_fmt = comptime cf: {
-                const info = @typeInfo(T);
-                const defs = switch (info) {
-                    builtin.TypeId.Struct => |s| s.defs,
-                    builtin.TypeId.Union => |u| u.defs,
-                    builtin.TypeId.Enum => |e| e.defs,
-                    else => unreachable,
-                };
-
-                for (defs) |def| {
-                    if (mem.eql(u8, def.name, "format")) {
-                        break :cf true;
-                    }
-                }
-                break :cf false;
-            };
-            if (has_cust_fmt) return value.format(fmt, context, Errors, output);
+            if (comptime std.meta.trait.hasFn("format")(T)) return value.format(fmt, context, Errors, output);
 
             try output(context, @typeName(T));
             switch (comptime @typeId(T)) {
std/meta.zig
@@ -160,16 +160,16 @@ test "std.meta.containerLayout" {
     testing.expect(containerLayout(U3) == TypeInfo.ContainerLayout.Extern);
 }
 
-pub fn definitions(comptime T: type) []TypeInfo.Definition {
+pub fn declarations(comptime T: type) []TypeInfo.Declaration {
     return switch (@typeInfo(T)) {
-        TypeId.Struct => |info| info.defs,
-        TypeId.Enum => |info| info.defs,
-        TypeId.Union => |info| info.defs,
+        TypeId.Struct => |info| info.decls,
+        TypeId.Enum => |info| info.decls,
+        TypeId.Union => |info| info.decls,
         else => @compileError("Expected struct, enum or union type, found '" ++ @typeName(T) ++ "'"),
     };
 }
 
-test "std.meta.definitions" {
+test "std.meta.declarations" {
     const E1 = enum {
         A,
 
@@ -184,28 +184,28 @@ test "std.meta.definitions" {
         fn a() void {}
     };
 
-    const defs = comptime [][]TypeInfo.Definition{
-        definitions(E1),
-        definitions(S1),
-        definitions(U1),
+    const decls = comptime [][]TypeInfo.Declaration{
+        declarations(E1),
+        declarations(S1),
+        declarations(U1),
     };
 
-    inline for (defs) |def| {
-        testing.expect(def.len == 1);
-        testing.expect(comptime mem.eql(u8, def[0].name, "a"));
+    inline for (decls) |decl| {
+        testing.expect(decl.len == 1);
+        testing.expect(comptime mem.eql(u8, decl[0].name, "a"));
     }
 }
 
-pub fn definitionInfo(comptime T: type, comptime def_name: []const u8) TypeInfo.Definition {
-    inline for (comptime definitions(T)) |def| {
-        if (comptime mem.eql(u8, def.name, def_name))
-            return def;
+pub fn declarationInfo(comptime T: type, comptime decl_name: []const u8) TypeInfo.Declaration {
+    inline for (comptime declarations(T)) |decl| {
+        if (comptime mem.eql(u8, decl.name, decl_name))
+            return decl;
     }
 
-    @compileError("'" ++ @typeName(T) ++ "' has no definition '" ++ def_name ++ "'");
+    @compileError("'" ++ @typeName(T) ++ "' has no declaration '" ++ decl_name ++ "'");
 }
 
-test "std.meta.definitionInfo" {
+test "std.meta.declarationInfo" {
     const E1 = enum {
         A,
 
@@ -220,10 +220,10 @@ test "std.meta.definitionInfo" {
         fn a() void {}
     };
 
-    const infos = comptime []TypeInfo.Definition{
-        definitionInfo(E1, "a"),
-        definitionInfo(S1, "a"),
-        definitionInfo(U1, "a"),
+    const infos = comptime []TypeInfo.Declaration{
+        declarationInfo(E1, "a"),
+        declarationInfo(S1, "a"),
+        declarationInfo(U1, "a"),
     };
 
     inline for (infos) |info| {
test/stage1/behavior/type_info.zig
@@ -177,7 +177,7 @@ fn testEnum() void {
     expect(mem.eql(u8, os_info.Enum.fields[1].name, "Macos"));
     expect(os_info.Enum.fields[3].value == 3);
     expect(os_info.Enum.tag_type == u2);
-    expect(os_info.Enum.defs.len == 0);
+    expect(os_info.Enum.decls.len == 0);
 }
 
 test "type info: union info" {
@@ -194,7 +194,7 @@ fn testUnion() void {
     expect(typeinfo_info.Union.fields[4].enum_field != null);
     expect(typeinfo_info.Union.fields[4].enum_field.?.value == 4);
     expect(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int));
-    expect(typeinfo_info.Union.defs.len == 21);
+    expect(typeinfo_info.Union.decls.len == 21);
 
     const TestNoTagUnion = union {
         Foo: void,
@@ -232,12 +232,12 @@ fn testStruct() void {
     expect(struct_info.Struct.fields.len == 3);
     expect(struct_info.Struct.fields[1].offset == null);
     expect(struct_info.Struct.fields[2].field_type == *TestStruct);
-    expect(struct_info.Struct.defs.len == 2);
-    expect(struct_info.Struct.defs[0].is_pub);
-    expect(!struct_info.Struct.defs[0].data.Fn.is_extern);
-    expect(struct_info.Struct.defs[0].data.Fn.lib_name == null);
-    expect(struct_info.Struct.defs[0].data.Fn.return_type == void);
-    expect(struct_info.Struct.defs[0].data.Fn.fn_type == fn (*const TestStruct) void);
+    expect(struct_info.Struct.decls.len == 2);
+    expect(struct_info.Struct.decls[0].is_pub);
+    expect(!struct_info.Struct.decls[0].data.Fn.is_extern);
+    expect(struct_info.Struct.decls[0].data.Fn.lib_name == null);
+    expect(struct_info.Struct.decls[0].data.Fn.return_type == void);
+    expect(struct_info.Struct.decls[0].data.Fn.fn_type == fn (*const TestStruct) void);
 }
 
 const TestStruct = packed struct {