| ... | @@ -9794,6 +9794,58 @@ static TypeTableEntry *ir_analyze_instruction_bin_op(IrAnalyze *ira, IrInstructi | ... | @@ -9794,6 +9794,58 @@ static TypeTableEntry *ir_analyze_instruction_bin_op(IrAnalyze *ira, IrInstructi |
| 9794 | zig_unreachable(); | 9794 | zig_unreachable(); |
| 9795 | } | 9795 | } |
| 9796 | | 9796 | |
| | 9797 | enum VarClassRequired { |
| | 9798 | VarClassRequiredAny, |
| | 9799 | VarClassRequiredConst, |
| | 9800 | VarClassRequiredIllegal, |
| | 9801 | }; |
| | 9802 | |
| | 9803 | static VarClassRequired get_var_class_required(TypeTableEntry *type_entry) { |
| | 9804 | switch (type_entry->id) { |
| | 9805 | case TypeTableEntryIdInvalid: |
| | 9806 | zig_unreachable(); |
| | 9807 | case TypeTableEntryIdUnreachable: |
| | 9808 | case TypeTableEntryIdVar: |
| | 9809 | return VarClassRequiredIllegal; |
| | 9810 | case TypeTableEntryIdBool: |
| | 9811 | case TypeTableEntryIdInt: |
| | 9812 | case TypeTableEntryIdFloat: |
| | 9813 | case TypeTableEntryIdVoid: |
| | 9814 | case TypeTableEntryIdPureError: |
| | 9815 | case TypeTableEntryIdFn: |
| | 9816 | case TypeTableEntryIdEnumTag: |
| | 9817 | return VarClassRequiredAny; |
| | 9818 | case TypeTableEntryIdNumLitFloat: |
| | 9819 | case TypeTableEntryIdNumLitInt: |
| | 9820 | case TypeTableEntryIdUndefLit: |
| | 9821 | case TypeTableEntryIdBlock: |
| | 9822 | case TypeTableEntryIdNullLit: |
| | 9823 | case TypeTableEntryIdOpaque: |
| | 9824 | case TypeTableEntryIdMetaType: |
| | 9825 | case TypeTableEntryIdNamespace: |
| | 9826 | case TypeTableEntryIdBoundFn: |
| | 9827 | case TypeTableEntryIdArgTuple: |
| | 9828 | return VarClassRequiredConst; |
| | 9829 | |
| | 9830 | case TypeTableEntryIdPointer: |
| | 9831 | return get_var_class_required(type_entry->data.pointer.child_type); |
| | 9832 | case TypeTableEntryIdArray: |
| | 9833 | return get_var_class_required(type_entry->data.array.child_type); |
| | 9834 | case TypeTableEntryIdMaybe: |
| | 9835 | return get_var_class_required(type_entry->data.maybe.child_type); |
| | 9836 | case TypeTableEntryIdErrorUnion: |
| | 9837 | return get_var_class_required(type_entry->data.error.child_type); |
| | 9838 | |
| | 9839 | case TypeTableEntryIdStruct: |
| | 9840 | case TypeTableEntryIdEnum: |
| | 9841 | case TypeTableEntryIdUnion: |
| | 9842 | // TODO check the fields of these things and make sure that they don't recursively |
| | 9843 | // contain any of the other variable classes |
| | 9844 | return VarClassRequiredAny; |
| | 9845 | } |
| | 9846 | zig_unreachable(); |
| | 9847 | } |
| | 9848 | |
| 9797 | static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstructionDeclVar *decl_var_instruction) { | 9849 | static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstructionDeclVar *decl_var_instruction) { |
| 9798 | VariableTableEntry *var = decl_var_instruction->var; | 9850 | VariableTableEntry *var = decl_var_instruction->var; |
| 9799 | | 9851 | |
| ... | @@ -9803,10 +9855,6 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc | ... | @@ -9803,10 +9855,6 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc |
| 9803 | return var->value->type; | 9855 | return var->value->type; |
| 9804 | } | 9856 | } |
| 9805 | | 9857 | |
| 9806 | AstNodeVariableDeclaration *variable_declaration = &var->decl_node->data.variable_declaration; | | |
| 9807 | bool is_export = (variable_declaration->visib_mod == VisibModExport); | | |
| 9808 | bool is_extern = variable_declaration->is_extern; | | |
| 9809 | | | |
| 9810 | var->ref_count = 0; | 9858 | var->ref_count = 0; |
| 9811 | | 9859 | |
| 9812 | TypeTableEntry *explicit_type = nullptr; | 9860 | TypeTableEntry *explicit_type = nullptr; |
| ... | @@ -9824,59 +9872,30 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc | ... | @@ -9824,59 +9872,30 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc |
| 9824 | AstNode *source_node = decl_var_instruction->base.source_node; | 9872 | AstNode *source_node = decl_var_instruction->base.source_node; |
| 9825 | | 9873 | |
| 9826 | IrInstruction *casted_init_value = ir_implicit_cast(ira, init_value, explicit_type); | 9874 | IrInstruction *casted_init_value = ir_implicit_cast(ira, init_value, explicit_type); |
| | 9875 | bool is_comptime_var = ir_get_var_is_comptime(var); |
| | 9876 | |
| 9827 | TypeTableEntry *result_type = casted_init_value->value.type; | 9877 | TypeTableEntry *result_type = casted_init_value->value.type; |
| 9828 | if (type_is_invalid(result_type)) { | 9878 | if (type_is_invalid(result_type)) { |
| 9829 | result_type = ira->codegen->builtin_types.entry_invalid; | 9879 | result_type = ira->codegen->builtin_types.entry_invalid; |
| 9830 | } | 9880 | } else { |
| 9831 | | 9881 | switch (get_var_class_required(result_type)) { |
| 9832 | bool is_comptime_var = ir_get_var_is_comptime(var); | 9882 | case VarClassRequiredIllegal: |
| 9833 | | | |
| 9834 | switch (result_type->id) { | | |
| 9835 | case TypeTableEntryIdInvalid: | | |
| 9836 | break; // handled above | | |
| 9837 | case TypeTableEntryIdNumLitFloat: | | |
| 9838 | case TypeTableEntryIdNumLitInt: | | |
| 9839 | case TypeTableEntryIdUndefLit: | | |
| 9840 | if (is_export || is_extern || (!var->src_is_const && !is_comptime_var)) { | | |
| 9841 | ir_add_error_node(ira, source_node, buf_sprintf("unable to infer variable type")); | | |
| 9842 | result_type = ira->codegen->builtin_types.entry_invalid; | | |
| 9843 | } | | |
| 9844 | break; | | |
| 9845 | case TypeTableEntryIdUnreachable: | | |
| 9846 | case TypeTableEntryIdVar: | | |
| 9847 | case TypeTableEntryIdBlock: | | |
| 9848 | case TypeTableEntryIdNullLit: | | |
| 9849 | case TypeTableEntryIdOpaque: | | |
| 9850 | ir_add_error_node(ira, source_node, | | |
| 9851 | buf_sprintf("variable of type '%s' not allowed", buf_ptr(&result_type->name))); | | |
| 9852 | result_type = ira->codegen->builtin_types.entry_invalid; | | |
| 9853 | break; | | |
| 9854 | case TypeTableEntryIdMetaType: | | |
| 9855 | case TypeTableEntryIdNamespace: | | |
| 9856 | if (casted_init_value->value.special == ConstValSpecialRuntime) { | | |
| 9857 | ir_add_error_node(ira, source_node, | 9883 | ir_add_error_node(ira, source_node, |
| 9858 | buf_sprintf("variable of type '%s' must be constant", buf_ptr(&result_type->name))); | 9884 | buf_sprintf("variable of type '%s' not allowed", buf_ptr(&result_type->name))); |
| 9859 | result_type = ira->codegen->builtin_types.entry_invalid; | 9885 | result_type = ira->codegen->builtin_types.entry_invalid; |
| 9860 | } | 9886 | break; |
| 9861 | break; | 9887 | case VarClassRequiredConst: |
| 9862 | case TypeTableEntryIdVoid: | 9888 | if (!var->src_is_const && !is_comptime_var) { |
| 9863 | case TypeTableEntryIdBool: | 9889 | ir_add_error_node(ira, source_node, |
| 9864 | case TypeTableEntryIdInt: | 9890 | buf_sprintf("variable of type '%s' must be const or comptime", |
| 9865 | case TypeTableEntryIdFloat: | 9891 | buf_ptr(&result_type->name))); |
| 9866 | case TypeTableEntryIdPointer: | 9892 | result_type = ira->codegen->builtin_types.entry_invalid; |
| 9867 | case TypeTableEntryIdArray: | 9893 | } |
| 9868 | case TypeTableEntryIdStruct: | 9894 | break; |
| 9869 | case TypeTableEntryIdMaybe: | 9895 | case VarClassRequiredAny: |
| 9870 | case TypeTableEntryIdErrorUnion: | 9896 | // OK |
| 9871 | case TypeTableEntryIdPureError: | 9897 | break; |
| 9872 | case TypeTableEntryIdEnum: | 9898 | } |
| 9873 | case TypeTableEntryIdUnion: | | |
| 9874 | case TypeTableEntryIdFn: | | |
| 9875 | case TypeTableEntryIdBoundFn: | | |
| 9876 | case TypeTableEntryIdEnumTag: | | |
| 9877 | case TypeTableEntryIdArgTuple: | | |
| 9878 | // OK | | |
| 9879 | break; | | |
| 9880 | } | 9899 | } |
| 9881 | | 9900 | |
| 9882 | var->value->type = result_type; | 9901 | var->value->type = result_type; |