diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2017-09-09 22:46:08 -0400 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2017-09-09 22:46:08 -0400 |
| commit | bc0a60c7a6e772a40fc19becd46f89f34f502759 (patch) | |
| tree | ea48f9759ed2cb10146c441ef45db289729befe8 /src/ir.cpp | |
| parent | 5fdf3fa1954f8f8f2a4558723078c0b1400b8574 (diff) | |
| download | zig-bc0a60c7a6e772a40fc19becd46f89f34f502759.tar.gz zig-bc0a60c7a6e772a40fc19becd46f89f34f502759.zip | |
more compile errors for non-const variables of things
closes #456
Diffstat (limited to 'src/ir.cpp')
| -rw-r--r-- | src/ir.cpp | 123 |
1 files changed, 71 insertions, 52 deletions
diff --git a/src/ir.cpp b/src/ir.cpp index a30851d010..5771fd480d 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -9794,6 +9794,58 @@ static TypeTableEntry *ir_analyze_instruction_bin_op(IrAnalyze *ira, IrInstructi zig_unreachable(); } +enum VarClassRequired { + VarClassRequiredAny, + VarClassRequiredConst, + VarClassRequiredIllegal, +}; + +static VarClassRequired get_var_class_required(TypeTableEntry *type_entry) { + switch (type_entry->id) { + case TypeTableEntryIdInvalid: + zig_unreachable(); + case TypeTableEntryIdUnreachable: + case TypeTableEntryIdVar: + return VarClassRequiredIllegal; + case TypeTableEntryIdBool: + case TypeTableEntryIdInt: + case TypeTableEntryIdFloat: + case TypeTableEntryIdVoid: + case TypeTableEntryIdPureError: + case TypeTableEntryIdFn: + case TypeTableEntryIdEnumTag: + return VarClassRequiredAny; + case TypeTableEntryIdNumLitFloat: + case TypeTableEntryIdNumLitInt: + case TypeTableEntryIdUndefLit: + case TypeTableEntryIdBlock: + case TypeTableEntryIdNullLit: + case TypeTableEntryIdOpaque: + case TypeTableEntryIdMetaType: + case TypeTableEntryIdNamespace: + case TypeTableEntryIdBoundFn: + case TypeTableEntryIdArgTuple: + return VarClassRequiredConst; + + case TypeTableEntryIdPointer: + return get_var_class_required(type_entry->data.pointer.child_type); + case TypeTableEntryIdArray: + return get_var_class_required(type_entry->data.array.child_type); + case TypeTableEntryIdMaybe: + return get_var_class_required(type_entry->data.maybe.child_type); + case TypeTableEntryIdErrorUnion: + return get_var_class_required(type_entry->data.error.child_type); + + case TypeTableEntryIdStruct: + case TypeTableEntryIdEnum: + case TypeTableEntryIdUnion: + // TODO check the fields of these things and make sure that they don't recursively + // contain any of the other variable classes + return VarClassRequiredAny; + } + zig_unreachable(); +} + static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstructionDeclVar *decl_var_instruction) { VariableTableEntry *var = decl_var_instruction->var; @@ -9803,10 +9855,6 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc return var->value->type; } - AstNodeVariableDeclaration *variable_declaration = &var->decl_node->data.variable_declaration; - bool is_export = (variable_declaration->visib_mod == VisibModExport); - bool is_extern = variable_declaration->is_extern; - var->ref_count = 0; TypeTableEntry *explicit_type = nullptr; @@ -9824,59 +9872,30 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc AstNode *source_node = decl_var_instruction->base.source_node; IrInstruction *casted_init_value = ir_implicit_cast(ira, init_value, explicit_type); + bool is_comptime_var = ir_get_var_is_comptime(var); + TypeTableEntry *result_type = casted_init_value->value.type; if (type_is_invalid(result_type)) { result_type = ira->codegen->builtin_types.entry_invalid; - } - - bool is_comptime_var = ir_get_var_is_comptime(var); - - switch (result_type->id) { - case TypeTableEntryIdInvalid: - break; // handled above - case TypeTableEntryIdNumLitFloat: - case TypeTableEntryIdNumLitInt: - case TypeTableEntryIdUndefLit: - if (is_export || is_extern || (!var->src_is_const && !is_comptime_var)) { - ir_add_error_node(ira, source_node, buf_sprintf("unable to infer variable type")); - result_type = ira->codegen->builtin_types.entry_invalid; - } - break; - case TypeTableEntryIdUnreachable: - case TypeTableEntryIdVar: - case TypeTableEntryIdBlock: - case TypeTableEntryIdNullLit: - case TypeTableEntryIdOpaque: - ir_add_error_node(ira, source_node, - buf_sprintf("variable of type '%s' not allowed", buf_ptr(&result_type->name))); - result_type = ira->codegen->builtin_types.entry_invalid; - break; - case TypeTableEntryIdMetaType: - case TypeTableEntryIdNamespace: - if (casted_init_value->value.special == ConstValSpecialRuntime) { + } else { + switch (get_var_class_required(result_type)) { + case VarClassRequiredIllegal: ir_add_error_node(ira, source_node, - buf_sprintf("variable of type '%s' must be constant", buf_ptr(&result_type->name))); + buf_sprintf("variable of type '%s' not allowed", buf_ptr(&result_type->name))); result_type = ira->codegen->builtin_types.entry_invalid; - } - break; - case TypeTableEntryIdVoid: - case TypeTableEntryIdBool: - case TypeTableEntryIdInt: - case TypeTableEntryIdFloat: - case TypeTableEntryIdPointer: - case TypeTableEntryIdArray: - case TypeTableEntryIdStruct: - case TypeTableEntryIdMaybe: - case TypeTableEntryIdErrorUnion: - case TypeTableEntryIdPureError: - case TypeTableEntryIdEnum: - case TypeTableEntryIdUnion: - case TypeTableEntryIdFn: - case TypeTableEntryIdBoundFn: - case TypeTableEntryIdEnumTag: - case TypeTableEntryIdArgTuple: - // OK - break; + break; + case VarClassRequiredConst: + if (!var->src_is_const && !is_comptime_var) { + ir_add_error_node(ira, source_node, + buf_sprintf("variable of type '%s' must be const or comptime", + buf_ptr(&result_type->name))); + result_type = ira->codegen->builtin_types.entry_invalid; + } + break; + case VarClassRequiredAny: + // OK + break; + } } var->value->type = result_type; |
