| ... | ... | @@ -109,6 +109,7 @@ static AstNode *first_executing_node(AstNode *node) { |
| 109 | 109 | case NodeTypeErrorType: |
| 110 | 110 | case NodeTypeTypeLiteral: |
| 111 | 111 | case NodeTypeContainerInitExpr: |
| 112 | case NodeTypeVarLiteral: |
| 112 | 113 | return node; |
| 113 | 114 | } |
| 114 | 115 | zig_unreachable(); |
| ... | ... | @@ -219,6 +220,7 @@ static int bits_needed_for_unsigned(uint64_t x) { |
| 219 | 220 | static bool type_is_complete(TypeTableEntry *type_entry) { |
| 220 | 221 | switch (type_entry->id) { |
| 221 | 222 | case TypeTableEntryIdInvalid: |
| 223 | case TypeTableEntryIdVar: |
| 222 | 224 | zig_unreachable(); |
| 223 | 225 | case TypeTableEntryIdStruct: |
| 224 | 226 | return type_entry->data.structure.complete; |
| ... | ... | @@ -919,39 +921,6 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor |
| 919 | 921 | fn_type_id.is_var_args = fn_proto->is_var_args; |
| 920 | 922 | fn_type_id.return_type = analyze_type_expr(g, import, context, fn_proto->return_type); |
| 921 | 923 | |
| 922 | | switch (fn_type_id.return_type->id) { |
| 923 | | case TypeTableEntryIdInvalid: |
| 924 | | fn_proto->skip = true; |
| 925 | | break; |
| 926 | | case TypeTableEntryIdNumLitFloat: |
| 927 | | case TypeTableEntryIdNumLitInt: |
| 928 | | case TypeTableEntryIdUndefLit: |
| 929 | | case TypeTableEntryIdNullLit: |
| 930 | | case TypeTableEntryIdNamespace: |
| 931 | | case TypeTableEntryIdGenericFn: |
| 932 | | fn_proto->skip = true; |
| 933 | | add_node_error(g, fn_proto->return_type, |
| 934 | | buf_sprintf("return type '%s' not allowed", buf_ptr(&fn_type_id.return_type->name))); |
| 935 | | break; |
| 936 | | case TypeTableEntryIdMetaType: |
| 937 | | case TypeTableEntryIdUnreachable: |
| 938 | | case TypeTableEntryIdVoid: |
| 939 | | case TypeTableEntryIdBool: |
| 940 | | case TypeTableEntryIdInt: |
| 941 | | case TypeTableEntryIdFloat: |
| 942 | | case TypeTableEntryIdPointer: |
| 943 | | case TypeTableEntryIdArray: |
| 944 | | case TypeTableEntryIdStruct: |
| 945 | | case TypeTableEntryIdMaybe: |
| 946 | | case TypeTableEntryIdErrorUnion: |
| 947 | | case TypeTableEntryIdPureError: |
| 948 | | case TypeTableEntryIdEnum: |
| 949 | | case TypeTableEntryIdUnion: |
| 950 | | case TypeTableEntryIdFn: |
| 951 | | case TypeTableEntryIdTypeDecl: |
| 952 | | break; |
| 953 | | } |
| 954 | | |
| 955 | 924 | for (int i = 0; i < fn_type_id.param_count; i += 1) { |
| 956 | 925 | AstNode *child = fn_proto->params.at(i); |
| 957 | 926 | assert(child->type == NodeTypeParamDecl); |
| ... | ... | @@ -996,6 +965,10 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor |
| 996 | 965 | case TypeTableEntryIdFn: |
| 997 | 966 | case TypeTableEntryIdTypeDecl: |
| 998 | 967 | break; |
| 968 | case TypeTableEntryIdVar: |
| 969 | // var types are treated as generic functions; if we get to this code we should |
| 970 | // already be an instantiated function. |
| 971 | zig_unreachable(); |
| 999 | 972 | } |
| 1000 | 973 | if (type_entry->id == TypeTableEntryIdInvalid) { |
| 1001 | 974 | fn_proto->skip = true; |
| ... | ... | @@ -1005,6 +978,42 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor |
| 1005 | 978 | param_info->is_noalias = child->data.param_decl.is_noalias; |
| 1006 | 979 | } |
| 1007 | 980 | |
| 981 | switch (fn_type_id.return_type->id) { |
| 982 | case TypeTableEntryIdInvalid: |
| 983 | fn_proto->skip = true; |
| 984 | break; |
| 985 | case TypeTableEntryIdNumLitFloat: |
| 986 | case TypeTableEntryIdNumLitInt: |
| 987 | case TypeTableEntryIdUndefLit: |
| 988 | case TypeTableEntryIdNullLit: |
| 989 | case TypeTableEntryIdNamespace: |
| 990 | case TypeTableEntryIdGenericFn: |
| 991 | fn_proto->skip = true; |
| 992 | add_node_error(g, fn_proto->return_type, |
| 993 | buf_sprintf("return type '%s' not allowed", buf_ptr(&fn_type_id.return_type->name))); |
| 994 | break; |
| 995 | case TypeTableEntryIdMetaType: |
| 996 | case TypeTableEntryIdUnreachable: |
| 997 | case TypeTableEntryIdVoid: |
| 998 | case TypeTableEntryIdBool: |
| 999 | case TypeTableEntryIdInt: |
| 1000 | case TypeTableEntryIdFloat: |
| 1001 | case TypeTableEntryIdPointer: |
| 1002 | case TypeTableEntryIdArray: |
| 1003 | case TypeTableEntryIdStruct: |
| 1004 | case TypeTableEntryIdMaybe: |
| 1005 | case TypeTableEntryIdErrorUnion: |
| 1006 | case TypeTableEntryIdPureError: |
| 1007 | case TypeTableEntryIdEnum: |
| 1008 | case TypeTableEntryIdUnion: |
| 1009 | case TypeTableEntryIdFn: |
| 1010 | case TypeTableEntryIdTypeDecl: |
| 1011 | break; |
| 1012 | case TypeTableEntryIdVar: |
| 1013 | zig_panic("TODO var return type"); |
| 1014 | } |
| 1015 | |
| 1016 | |
| 1008 | 1017 | if (fn_proto->skip) { |
| 1009 | 1018 | return g->builtin_types.entry_invalid; |
| 1010 | 1019 | } |
| ... | ... | @@ -1618,6 +1627,11 @@ static void preview_generic_fn_proto(CodeGen *g, ImportTableEntry *import, AstNo |
| 1618 | 1627 | node->data.struct_decl.generic_fn_type = get_generic_fn_type(g, node); |
| 1619 | 1628 | } |
| 1620 | 1629 | |
| 1630 | static bool get_is_generic_fn(AstNode *proto_node) { |
| 1631 | assert(proto_node->type == NodeTypeFnProto); |
| 1632 | return proto_node->data.fn_proto.inline_or_var_type_arg_count > 0; |
| 1633 | } |
| 1634 | |
| 1621 | 1635 | static void preview_fn_proto_instance(CodeGen *g, ImportTableEntry *import, AstNode *proto_node, |
| 1622 | 1636 | BlockContext *containing_context) |
| 1623 | 1637 | { |
| ... | ... | @@ -1628,7 +1642,7 @@ static void preview_fn_proto_instance(CodeGen *g, ImportTableEntry *import, AstN |
| 1628 | 1642 | } |
| 1629 | 1643 | |
| 1630 | 1644 | bool is_generic_instance = proto_node->data.fn_proto.generic_proto_node; |
| 1631 | | bool is_generic_fn = proto_node->data.fn_proto.inline_arg_count > 0; |
| 1645 | bool is_generic_fn = get_is_generic_fn(proto_node); |
| 1632 | 1646 | assert(!is_generic_instance || !is_generic_fn); |
| 1633 | 1647 | |
| 1634 | 1648 | AstNode *parent_decl = proto_node->data.fn_proto.top_level_decl.parent_decl; |
| ... | ... | @@ -1875,6 +1889,7 @@ static void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only) |
| 1875 | 1889 | case NodeTypeArrayType: |
| 1876 | 1890 | case NodeTypeErrorType: |
| 1877 | 1891 | case NodeTypeTypeLiteral: |
| 1892 | case NodeTypeVarLiteral: |
| 1878 | 1893 | zig_unreachable(); |
| 1879 | 1894 | } |
| 1880 | 1895 | |
| ... | ... | @@ -1936,6 +1951,9 @@ static bool type_has_codegen_value(TypeTableEntry *type_entry) { |
| 1936 | 1951 | |
| 1937 | 1952 | case TypeTableEntryIdTypeDecl: |
| 1938 | 1953 | return type_has_codegen_value(type_entry->data.type_decl.canonical_type); |
| 1954 | |
| 1955 | case TypeTableEntryIdVar: |
| 1956 | zig_unreachable(); |
| 1939 | 1957 | } |
| 1940 | 1958 | zig_unreachable(); |
| 1941 | 1959 | } |
| ... | ... | @@ -3374,6 +3392,9 @@ static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *im |
| 3374 | 3392 | add_node_error(g, node, |
| 3375 | 3393 | buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name))); |
| 3376 | 3394 | return g->builtin_types.entry_invalid; |
| 3395 | |
| 3396 | case TypeTableEntryIdVar: |
| 3397 | zig_unreachable(); |
| 3377 | 3398 | } |
| 3378 | 3399 | |
| 3379 | 3400 | ConstExprValue *op1_val = &get_resolved_expr(*op1)->const_val; |
| ... | ... | @@ -3751,20 +3772,22 @@ static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import, |
| 3751 | 3772 | } |
| 3752 | 3773 | |
| 3753 | 3774 | // Set name to nullptr to make the variable anonymous (not visible to programmer). |
| 3754 | | static VariableTableEntry *add_local_var(CodeGen *g, AstNode *source_node, ImportTableEntry *import, |
| 3755 | | BlockContext *context, Buf *name, TypeTableEntry *type_entry, bool is_const, AstNode *val_node) |
| 3775 | static VariableTableEntry *add_local_var_shadowable(CodeGen *g, AstNode *source_node, ImportTableEntry *import, |
| 3776 | BlockContext *context, Buf *name, TypeTableEntry *type_entry, bool is_const, AstNode *val_node, |
| 3777 | bool shadowable) |
| 3756 | 3778 | { |
| 3757 | 3779 | VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1); |
| 3758 | 3780 | variable_entry->type = type_entry; |
| 3759 | 3781 | variable_entry->block_context = context; |
| 3760 | 3782 | variable_entry->import = import; |
| 3783 | variable_entry->shadowable = shadowable; |
| 3761 | 3784 | |
| 3762 | 3785 | if (name) { |
| 3763 | 3786 | buf_init_from_buf(&variable_entry->name, name); |
| 3764 | 3787 | |
| 3765 | 3788 | if (type_entry->id != TypeTableEntryIdInvalid) { |
| 3766 | 3789 | VariableTableEntry *existing_var = find_variable(g, context, name); |
| 3767 | | if (existing_var) { |
| 3790 | if (existing_var && !existing_var->shadowable) { |
| 3768 | 3791 | ErrorMsg *msg = add_node_error(g, source_node, |
| 3769 | 3792 | buf_sprintf("redeclaration of variable '%s'", buf_ptr(name))); |
| 3770 | 3793 | add_error_note(g, msg, existing_var->decl_node, buf_sprintf("previous declaration is here")); |
| ... | ... | @@ -3805,6 +3828,12 @@ static VariableTableEntry *add_local_var(CodeGen *g, AstNode *source_node, Impor |
| 3805 | 3828 | return variable_entry; |
| 3806 | 3829 | } |
| 3807 | 3830 | |
| 3831 | static VariableTableEntry *add_local_var(CodeGen *g, AstNode *source_node, ImportTableEntry *import, |
| 3832 | BlockContext *context, Buf *name, TypeTableEntry *type_entry, bool is_const, AstNode *val_node) |
| 3833 | { |
| 3834 | return add_local_var_shadowable(g, source_node, import, context, name, type_entry, is_const, val_node, false); |
| 3835 | } |
| 3836 | |
| 3808 | 3837 | static TypeTableEntry *analyze_unwrap_error_expr(CodeGen *g, ImportTableEntry *import, |
| 3809 | 3838 | BlockContext *parent_context, TypeTableEntry *expected_type, AstNode *node) |
| 3810 | 3839 | { |
| ... | ... | @@ -5227,6 +5256,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry |
| 5227 | 5256 | case TypeTableEntryIdNullLit: |
| 5228 | 5257 | case TypeTableEntryIdNamespace: |
| 5229 | 5258 | case TypeTableEntryIdGenericFn: |
| 5259 | case TypeTableEntryIdVar: |
| 5230 | 5260 | add_node_error(g, expr_node, |
| 5231 | 5261 | buf_sprintf("type '%s' not eligible for @typeOf", buf_ptr(&type_entry->name))); |
| 5232 | 5262 | return g->builtin_types.entry_invalid; |
| ... | ... | @@ -5542,23 +5572,22 @@ static TypeTableEntry *analyze_fn_call_with_inline_args(CodeGen *g, ImportTableE |
| 5542 | 5572 | return g->builtin_types.entry_invalid; |
| 5543 | 5573 | } |
| 5544 | 5574 | |
| 5545 | | int inline_arg_count = decl_node->data.fn_proto.inline_arg_count; |
| 5546 | | assert(inline_arg_count > 0); |
| 5575 | int inline_or_var_type_arg_count = decl_node->data.fn_proto.inline_or_var_type_arg_count; |
| 5576 | assert(inline_or_var_type_arg_count > 0); |
| 5547 | 5577 | |
| 5548 | 5578 | BlockContext *child_context = decl_node->owner->block_context; |
| 5549 | 5579 | int next_generic_param_index = 0; |
| 5550 | 5580 | |
| 5551 | 5581 | GenericFnTypeId *generic_fn_type_id = allocate<GenericFnTypeId>(1); |
| 5552 | 5582 | generic_fn_type_id->decl_node = decl_node; |
| 5553 | | generic_fn_type_id->generic_param_count = inline_arg_count; |
| 5554 | | generic_fn_type_id->generic_params = allocate<GenericParamValue>(inline_arg_count); |
| 5583 | generic_fn_type_id->generic_param_count = inline_or_var_type_arg_count; |
| 5584 | generic_fn_type_id->generic_params = allocate<GenericParamValue>(inline_or_var_type_arg_count); |
| 5555 | 5585 | |
| 5586 | int next_impl_i = 0; |
| 5556 | 5587 | for (int call_i = 0; call_i < call_param_count; call_i += 1) { |
| 5557 | 5588 | int proto_i = call_i + struct_node_1_or_0; |
| 5558 | 5589 | AstNode *generic_param_decl_node = decl_node->data.fn_proto.params.at(proto_i); |
| 5559 | 5590 | assert(generic_param_decl_node->type == NodeTypeParamDecl); |
| 5560 | | bool is_inline = generic_param_decl_node->data.param_decl.is_inline; |
| 5561 | | if (!is_inline) continue; |
| 5562 | 5591 | |
| 5563 | 5592 | AstNode **generic_param_type_node = &generic_param_decl_node->data.param_decl.type; |
| 5564 | 5593 | TypeTableEntry *expected_param_type = analyze_type_expr(g, decl_node->owner, child_context, |
| ... | ... | @@ -5567,9 +5596,17 @@ static TypeTableEntry *analyze_fn_call_with_inline_args(CodeGen *g, ImportTableE |
| 5567 | 5596 | return expected_param_type; |
| 5568 | 5597 | } |
| 5569 | 5598 | |
| 5599 | bool is_var_type = (expected_param_type->id == TypeTableEntryIdVar); |
| 5600 | bool is_inline = generic_param_decl_node->data.param_decl.is_inline; |
| 5601 | if (!is_inline && !is_var_type) { |
| 5602 | next_impl_i += 1; |
| 5603 | continue; |
| 5604 | } |
| 5605 | |
| 5606 | |
| 5570 | 5607 | AstNode **param_node = &call_node->data.fn_call_expr.params.at(call_i); |
| 5571 | 5608 | TypeTableEntry *param_type = analyze_expression(g, import, parent_context, |
| 5572 | | expected_param_type, *param_node); |
| 5609 | is_var_type ? nullptr : expected_param_type, *param_node); |
| 5573 | 5610 | if (param_type->id == TypeTableEntryIdInvalid) { |
| 5574 | 5611 | return param_type; |
| 5575 | 5612 | } |
| ... | ... | @@ -5578,27 +5615,32 @@ static TypeTableEntry *analyze_fn_call_with_inline_args(CodeGen *g, ImportTableE |
| 5578 | 5615 | child_context = new_block_context(generic_param_decl_node, child_context); |
| 5579 | 5616 | |
| 5580 | 5617 | ConstExprValue *const_val = &get_resolved_expr(*param_node)->const_val; |
| 5581 | | if (const_val->ok) { |
| 5582 | | VariableTableEntry *var = add_local_var(g, generic_param_decl_node, decl_node->owner, child_context, |
| 5583 | | generic_param_decl_node->data.param_decl.name, param_type, true, *param_node); |
| 5584 | | // This generic function instance could be called with anything, so when this variable is read it |
| 5585 | | // needs to know that it depends on compile time variable data. |
| 5586 | | var->force_depends_on_compile_var = true; |
| 5587 | | } else { |
| 5618 | if (is_inline && !const_val->ok) { |
| 5588 | 5619 | add_node_error(g, *param_node, |
| 5589 | 5620 | buf_sprintf("unable to evaluate constant expression for inline parameter")); |
| 5590 | 5621 | |
| 5591 | 5622 | return g->builtin_types.entry_invalid; |
| 5592 | 5623 | } |
| 5593 | 5624 | |
| 5625 | VariableTableEntry *var = add_local_var_shadowable(g, generic_param_decl_node, decl_node->owner, child_context, |
| 5626 | generic_param_decl_node->data.param_decl.name, param_type, true, *param_node, true); |
| 5627 | // This generic function instance could be called with anything, so when this variable is read it |
| 5628 | // needs to know that it depends on compile time variable data. |
| 5629 | var->force_depends_on_compile_var = true; |
| 5630 | |
| 5594 | 5631 | GenericParamValue *generic_param_value = |
| 5595 | 5632 | &generic_fn_type_id->generic_params[next_generic_param_index]; |
| 5596 | 5633 | generic_param_value->type = param_type; |
| 5597 | | generic_param_value->node = *param_node; |
| 5634 | generic_param_value->node = is_inline ? *param_node : nullptr; |
| 5635 | generic_param_value->impl_index = next_impl_i; |
| 5598 | 5636 | next_generic_param_index += 1; |
| 5637 | |
| 5638 | if (!is_inline) { |
| 5639 | next_impl_i += 1; |
| 5640 | } |
| 5599 | 5641 | } |
| 5600 | 5642 | |
| 5601 | | assert(next_generic_param_index == inline_arg_count); |
| 5643 | assert(next_generic_param_index == inline_or_var_type_arg_count); |
| 5602 | 5644 | |
| 5603 | 5645 | auto entry = g->generic_table.maybe_get(generic_fn_type_id); |
| 5604 | 5646 | FnTableEntry *impl_fn; |
| ... | ... | @@ -5612,8 +5654,23 @@ static TypeTableEntry *analyze_fn_call_with_inline_args(CodeGen *g, ImportTableE |
| 5612 | 5654 | &g->next_node_index, AstCloneSpecialOmitInlineParams); |
| 5613 | 5655 | AstNode *impl_decl_node = impl_fn_def_node->data.fn_def.fn_proto; |
| 5614 | 5656 | impl_decl_node->data.fn_proto.inline_arg_count = 0; |
| 5657 | impl_decl_node->data.fn_proto.inline_or_var_type_arg_count = 0; |
| 5615 | 5658 | impl_decl_node->data.fn_proto.generic_proto_node = decl_node; |
| 5616 | 5659 | |
| 5660 | // replace var arg types with actual types |
| 5661 | for (int generic_arg_i = 0; generic_arg_i < inline_or_var_type_arg_count; generic_arg_i += 1) { |
| 5662 | GenericParamValue *generic_param_value = &generic_fn_type_id->generic_params[generic_arg_i]; |
| 5663 | if (!generic_param_value->node) { |
| 5664 | int impl_i = generic_param_value->impl_index; |
| 5665 | AstNode *impl_param_decl_node = impl_decl_node->data.fn_proto.params.at(impl_i); |
| 5666 | assert(impl_param_decl_node->type == NodeTypeParamDecl); |
| 5667 | |
| 5668 | impl_param_decl_node->data.param_decl.type = create_ast_type_node(g, import, |
| 5669 | generic_param_value->type, impl_param_decl_node); |
| 5670 | normalize_parent_ptrs(impl_param_decl_node); |
| 5671 | } |
| 5672 | } |
| 5673 | |
| 5617 | 5674 | preview_fn_proto_instance(g, import, impl_decl_node, child_context); |
| 5618 | 5675 | g->generic_table.put(generic_fn_type_id, impl_decl_node); |
| 5619 | 5676 | impl_fn = impl_decl_node->data.fn_proto.fn_table_entry; |
| ... | ... | @@ -5660,6 +5717,9 @@ static TypeTableEntry *analyze_generic_fn_call(CodeGen *g, ImportTableEntry *imp |
| 5660 | 5717 | if (expected_param_type->id == TypeTableEntryIdInvalid) { |
| 5661 | 5718 | return expected_param_type; |
| 5662 | 5719 | } |
| 5720 | |
| 5721 | |
| 5722 | |
| 5663 | 5723 | AstNode **param_node = &node->data.fn_call_expr.params.at(i); |
| 5664 | 5724 | |
| 5665 | 5725 | TypeTableEntry *param_type = analyze_expression(g, import, parent_context, expected_param_type, |
| ... | ... | @@ -6605,6 +6665,9 @@ static TypeTableEntry *analyze_expression_pointer_only(CodeGen *g, ImportTableEn |
| 6605 | 6665 | case NodeTypeSwitchExpr: |
| 6606 | 6666 | return_type = analyze_switch_expr(g, import, context, expected_type, node); |
| 6607 | 6667 | break; |
| 6668 | case NodeTypeVarLiteral: |
| 6669 | return_type = resolve_expr_const_val_as_type(g, node, g->builtin_types.entry_var, false); |
| 6670 | break; |
| 6608 | 6671 | case NodeTypeSwitchProng: |
| 6609 | 6672 | case NodeTypeSwitchRange: |
| 6610 | 6673 | case NodeTypeDirective: |
| ... | ... | @@ -6750,18 +6813,25 @@ static void add_top_level_decl(CodeGen *g, ImportTableEntry *import, BlockContex |
| 6750 | 6813 | } |
| 6751 | 6814 | } |
| 6752 | 6815 | |
| 6753 | | static int fn_proto_inline_arg_count(AstNode *proto_node) { |
| 6816 | static void count_inline_and_var_args(AstNode *proto_node) { |
| 6754 | 6817 | assert(proto_node->type == NodeTypeFnProto); |
| 6755 | | int result = 0; |
| 6818 | |
| 6819 | int *inline_arg_count = &proto_node->data.fn_proto.inline_arg_count; |
| 6820 | int *inline_or_var_type_arg_count = &proto_node->data.fn_proto.inline_or_var_type_arg_count; |
| 6821 | |
| 6822 | *inline_arg_count = 0; |
| 6823 | *inline_or_var_type_arg_count = 0; |
| 6824 | |
| 6756 | 6825 | for (int i = 0; i < proto_node->data.fn_proto.params.length; i += 1) { |
| 6757 | 6826 | AstNode *param_node = proto_node->data.fn_proto.params.at(i); |
| 6758 | 6827 | assert(param_node->type == NodeTypeParamDecl); |
| 6759 | | result += param_node->data.param_decl.is_inline ? 1 : 0; |
| 6828 | bool is_inline = param_node->data.param_decl.is_inline; |
| 6829 | *inline_arg_count += is_inline ? 1 : 0; |
| 6830 | *inline_or_var_type_arg_count += (is_inline || |
| 6831 | param_node->data.param_decl.type->type == NodeTypeVarLiteral) ? 1 : 0; |
| 6760 | 6832 | } |
| 6761 | | return result; |
| 6762 | 6833 | } |
| 6763 | 6834 | |
| 6764 | | |
| 6765 | 6835 | static void scan_decls(CodeGen *g, ImportTableEntry *import, BlockContext *context, AstNode *node) { |
| 6766 | 6836 | switch (node->type) { |
| 6767 | 6837 | case NodeTypeRoot: |
| ... | ... | @@ -6804,7 +6874,7 @@ static void scan_decls(CodeGen *g, ImportTableEntry *import, BlockContext *conte |
| 6804 | 6874 | add_node_error(g, node, buf_sprintf("missing function name")); |
| 6805 | 6875 | break; |
| 6806 | 6876 | } |
| 6807 | | node->data.fn_proto.inline_arg_count = fn_proto_inline_arg_count(node); |
| 6877 | count_inline_and_var_args(node); |
| 6808 | 6878 | |
| 6809 | 6879 | add_top_level_decl(g, import, context, node, fn_name); |
| 6810 | 6880 | break; |
| ... | ... | @@ -6861,6 +6931,7 @@ static void scan_decls(CodeGen *g, ImportTableEntry *import, BlockContext *conte |
| 6861 | 6931 | case NodeTypeArrayType: |
| 6862 | 6932 | case NodeTypeErrorType: |
| 6863 | 6933 | case NodeTypeTypeLiteral: |
| 6934 | case NodeTypeVarLiteral: |
| 6864 | 6935 | zig_unreachable(); |
| 6865 | 6936 | } |
| 6866 | 6937 | } |
| ... | ... | @@ -7118,6 +7189,8 @@ Expr *get_resolved_expr(AstNode *node) { |
| 7118 | 7189 | return &node->data.switch_expr.resolved_expr; |
| 7119 | 7190 | case NodeTypeFnProto: |
| 7120 | 7191 | return &node->data.fn_proto.resolved_expr; |
| 7192 | case NodeTypeVarLiteral: |
| 7193 | return &node->data.var_literal.resolved_expr; |
| 7121 | 7194 | case NodeTypeSwitchProng: |
| 7122 | 7195 | case NodeTypeSwitchRange: |
| 7123 | 7196 | case NodeTypeRoot: |
| ... | ... | @@ -7192,6 +7265,7 @@ static TopLevelDecl *get_as_top_level_decl(AstNode *node) { |
| 7192 | 7265 | case NodeTypeArrayType: |
| 7193 | 7266 | case NodeTypeErrorType: |
| 7194 | 7267 | case NodeTypeTypeLiteral: |
| 7268 | case NodeTypeVarLiteral: |
| 7195 | 7269 | zig_unreachable(); |
| 7196 | 7270 | } |
| 7197 | 7271 | zig_unreachable(); |
| ... | ... | @@ -7250,6 +7324,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) { |
| 7250 | 7324 | case TypeTableEntryIdNullLit: |
| 7251 | 7325 | case TypeTableEntryIdNamespace: |
| 7252 | 7326 | case TypeTableEntryIdGenericFn: |
| 7327 | case TypeTableEntryIdVar: |
| 7253 | 7328 | zig_unreachable(); |
| 7254 | 7329 | case TypeTableEntryIdUnreachable: |
| 7255 | 7330 | case TypeTableEntryIdVoid: |
| ... | ... | @@ -7392,6 +7467,7 @@ static uint32_t hash_const_val(TypeTableEntry *type, ConstExprValue *const_val) |
| 7392 | 7467 | case TypeTableEntryIdGenericFn: |
| 7393 | 7468 | case TypeTableEntryIdInvalid: |
| 7394 | 7469 | case TypeTableEntryIdUnreachable: |
| 7470 | case TypeTableEntryIdVar: |
| 7395 | 7471 | zig_unreachable(); |
| 7396 | 7472 | } |
| 7397 | 7473 | zig_unreachable(); |
| ... | ... | @@ -7402,9 +7478,12 @@ uint32_t generic_fn_type_id_hash(GenericFnTypeId *id) { |
| 7402 | 7478 | result += hash_ptr(id->decl_node); |
| 7403 | 7479 | for (int i = 0; i < id->generic_param_count; i += 1) { |
| 7404 | 7480 | GenericParamValue *generic_param = &id->generic_params[i]; |
| 7405 | | ConstExprValue *const_val = &get_resolved_expr(generic_param->node)->const_val; |
| 7406 | | assert(const_val->ok); |
| 7407 | | result += hash_const_val(generic_param->type, const_val); |
| 7481 | if (generic_param->node) { |
| 7482 | ConstExprValue *const_val = &get_resolved_expr(generic_param->node)->const_val; |
| 7483 | assert(const_val->ok); |
| 7484 | result += hash_const_val(generic_param->type, const_val); |
| 7485 | } |
| 7486 | result += hash_ptr(generic_param->type); |
| 7408 | 7487 | } |
| 7409 | 7488 | return result; |
| 7410 | 7489 | } |
| ... | ... | @@ -7415,13 +7494,17 @@ bool generic_fn_type_id_eql(GenericFnTypeId *a, GenericFnTypeId *b) { |
| 7415 | 7494 | for (int i = 0; i < a->generic_param_count; i += 1) { |
| 7416 | 7495 | GenericParamValue *a_val = &a->generic_params[i]; |
| 7417 | 7496 | GenericParamValue *b_val = &b->generic_params[i]; |
| 7418 | | assert(a_val->type == b_val->type); |
| 7419 | | ConstExprValue *a_const_val = &get_resolved_expr(a_val->node)->const_val; |
| 7420 | | ConstExprValue *b_const_val = &get_resolved_expr(b_val->node)->const_val; |
| 7421 | | assert(a_const_val->ok); |
| 7422 | | assert(b_const_val->ok); |
| 7423 | | if (!const_values_equal(a_const_val, b_const_val, a_val->type)) { |
| 7424 | | return false; |
| 7497 | if (a_val->type != b_val->type) return false; |
| 7498 | if (a_val->node && b_val->node) { |
| 7499 | ConstExprValue *a_const_val = &get_resolved_expr(a_val->node)->const_val; |
| 7500 | ConstExprValue *b_const_val = &get_resolved_expr(b_val->node)->const_val; |
| 7501 | assert(a_const_val->ok); |
| 7502 | assert(b_const_val->ok); |
| 7503 | if (!const_values_equal(a_const_val, b_const_val, a_val->type)) { |
| 7504 | return false; |
| 7505 | } |
| 7506 | } else { |
| 7507 | assert(!a_val->node && !b_val->node); |
| 7425 | 7508 | } |
| 7426 | 7509 | } |
| 7427 | 7510 | return true; |
| ... | ... | @@ -7457,6 +7540,7 @@ static TypeTableEntry *type_of_first_thing_in_memory(TypeTableEntry *type_entry) |
| 7457 | 7540 | case TypeTableEntryIdVoid: |
| 7458 | 7541 | case TypeTableEntryIdNamespace: |
| 7459 | 7542 | case TypeTableEntryIdGenericFn: |
| 7543 | case TypeTableEntryIdVar: |
| 7460 | 7544 | zig_unreachable(); |
| 7461 | 7545 | case TypeTableEntryIdArray: |
| 7462 | 7546 | return type_of_first_thing_in_memory(type_entry->data.array.child_type); |