authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-04-19 19:37:25-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-04-19 19:37:25-07:00
log04364c45cefbba9451af202ceab5ae528cc8bbaa
treec43f61b9f29d6754b23b55317602a22b5bfc7cb3
parent36c6acfc76eeeed1498b5cc9ecb3137214e69bbf

fix casting with imported symbol not working


4 files changed, 31 insertions(+), 40 deletions(-)

src/analyze.cpp+14-39
...@@ -755,7 +755,7 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node) {...@@ -755,7 +755,7 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node) {
755755
756 ConstExprValue *const_val = &expr->const_val;756 ConstExprValue *const_val = &expr->const_val;
757 if (!const_val->ok) {757 if (!const_val->ok) {
758 add_node_error(g, node, buf_sprintf("unable to resolve constant expression"));758 add_node_error(g, node, buf_sprintf("unable to evaluate constant expression"));
759 return g->builtin_types.entry_invalid;759 return g->builtin_types.entry_invalid;
760 }760 }
761761
...@@ -867,7 +867,7 @@ static Buf *resolve_const_expr_str(CodeGen *g, ImportTableEntry *import, BlockCo...@@ -867,7 +867,7 @@ static Buf *resolve_const_expr_str(CodeGen *g, ImportTableEntry *import, BlockCo
867 ConstExprValue *const_str_val = &get_resolved_expr(*node)->const_val;867 ConstExprValue *const_str_val = &get_resolved_expr(*node)->const_val;
868868
869 if (!const_str_val->ok) {869 if (!const_str_val->ok) {
870 add_node_error(g, *node, buf_sprintf("unable to resolve constant expression"));870 add_node_error(g, *node, buf_sprintf("unable to evaluate constant expression"));
871 return nullptr;871 return nullptr;
872 }872 }
873873
...@@ -896,7 +896,7 @@ static bool resolve_const_expr_bool(CodeGen *g, ImportTableEntry *import, BlockC...@@ -896,7 +896,7 @@ static bool resolve_const_expr_bool(CodeGen *g, ImportTableEntry *import, BlockC
896 ConstExprValue *const_bool_val = &get_resolved_expr(*node)->const_val;896 ConstExprValue *const_bool_val = &get_resolved_expr(*node)->const_val;
897897
898 if (!const_bool_val->ok) {898 if (!const_bool_val->ok) {
899 add_node_error(g, *node, buf_sprintf("unable to resolve constant expression"));899 add_node_error(g, *node, buf_sprintf("unable to evaluate constant expression"));
900 return false;900 return false;
901 }901 }
902902
...@@ -2424,8 +2424,6 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i...@@ -2424,8 +2424,6 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
24242424
2425 if (child_type->id == TypeTableEntryIdInvalid) {2425 if (child_type->id == TypeTableEntryIdInvalid) {
2426 return g->builtin_types.entry_invalid;2426 return g->builtin_types.entry_invalid;
2427 } else if (wrapped_in_fn_call) {
2428 return resolve_expr_const_val_as_type(g, node, child_type);
2429 } else if (child_type->id == TypeTableEntryIdEnum) {2427 } else if (child_type->id == TypeTableEntryIdEnum) {
2430 AstNode *container_init_node = node->data.field_access_expr.container_init_expr_node;2428 AstNode *container_init_node = node->data.field_access_expr.container_init_expr_node;
2431 AstNode *value_node;2429 AstNode *value_node;
...@@ -2464,6 +2462,8 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i...@@ -2464,6 +2462,8 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
2464 }2462 }
2465 } else if (child_type->id == TypeTableEntryIdPureError) {2463 } else if (child_type->id == TypeTableEntryIdPureError) {
2466 return analyze_error_literal_expr(g, import, context, node, field_name);2464 return analyze_error_literal_expr(g, import, context, node, field_name);
2465 } else if (wrapped_in_fn_call) { // this branch should go last, before the error in the else case
2466 return resolve_expr_const_val_as_type(g, node, child_type);
2467 } else {2467 } else {
2468 add_node_error(g, node,2468 add_node_error(g, node,
2469 buf_sprintf("type '%s' does not support field access", buf_ptr(&struct_type->name)));2469 buf_sprintf("type '%s' does not support field access", buf_ptr(&struct_type->name)));
...@@ -4605,13 +4605,13 @@ static TypeTableEntry *analyze_fn_call_ptr(CodeGen *g, ImportTableEntry *import,...@@ -4605,13 +4605,13 @@ static TypeTableEntry *analyze_fn_call_ptr(CodeGen *g, ImportTableEntry *import,
4605 }4605 }
46064606
4607 FnTableEntry *fn_table_entry = node->data.fn_call_expr.fn_entry;4607 FnTableEntry *fn_table_entry = node->data.fn_call_expr.fn_entry;
4608 ConstExprValue *result_val = &get_resolved_expr(node)->const_val;
4608 if (ok_invocation && fn_table_entry && fn_table_entry->is_pure) {4609 if (ok_invocation && fn_table_entry && fn_table_entry->is_pure) {
4609 if (fn_table_entry->anal_state == FnAnalStateReady) {4610 if (fn_table_entry->anal_state == FnAnalStateReady) {
4610 analyze_fn_body(g, fn_table_entry);4611 analyze_fn_body(g, fn_table_entry);
4611 }4612 }
4612 if (all_args_const_expr) {4613 if (all_args_const_expr) {
4613 if (fn_table_entry->is_pure && fn_table_entry->anal_state == FnAnalStateComplete) {4614 if (fn_table_entry->is_pure && fn_table_entry->anal_state == FnAnalStateComplete) {
4614 ConstExprValue *result_val = &get_resolved_expr(node)->const_val;
4615 if (eval_fn(g, node, fn_table_entry, result_val, 1000, struct_node)) {4615 if (eval_fn(g, node, fn_table_entry, result_val, 1000, struct_node)) {
4616 // function evaluation generated an error4616 // function evaluation generated an error
4617 return g->builtin_types.entry_invalid;4617 return g->builtin_types.entry_invalid;
...@@ -4626,7 +4626,11 @@ static TypeTableEntry *analyze_fn_call_ptr(CodeGen *g, ImportTableEntry *import,...@@ -4626,7 +4626,11 @@ static TypeTableEntry *analyze_fn_call_ptr(CodeGen *g, ImportTableEntry *import,
4626 }4626 }
46274627
4628 if (handle_is_ptr(return_type)) {4628 if (handle_is_ptr(return_type)) {
4629 context->fn_entry->cast_alloca_list.append(node);4629 if (context->fn_entry) {
4630 context->fn_entry->cast_alloca_list.append(node);
4631 } else if (!result_val->ok) {
4632 add_node_error(g, node, buf_sprintf("unable to evaluate constant expression"));
4633 }
4630 }4634 }
46314635
4632 return return_type;4636 return return_type;
...@@ -4693,7 +4697,7 @@ static TypeTableEntry *analyze_generic_fn_call(CodeGen *g, ImportTableEntry *imp...@@ -4693,7 +4697,7 @@ static TypeTableEntry *analyze_generic_fn_call(CodeGen *g, ImportTableEntry *imp
4693 add_local_var(g, generic_param_decl_node, decl_node->owner, child_context,4697 add_local_var(g, generic_param_decl_node, decl_node->owner, child_context,
4694 &generic_param_decl_node->data.param_decl.name, param_type, true, *param_node);4698 &generic_param_decl_node->data.param_decl.name, param_type, true, *param_node);
4695 } else {4699 } else {
4696 add_node_error(g, *param_node, buf_sprintf("unable to resolve constant expression"));4700 add_node_error(g, *param_node, buf_sprintf("unable to evaluate constant expression"));
46974701
4698 add_local_var(g, generic_param_decl_node, decl_node->owner, child_context,4702 add_local_var(g, generic_param_decl_node, decl_node->owner, child_context,
4699 &generic_param_decl_node->data.param_decl.name, g->builtin_types.entry_invalid,4703 &generic_param_decl_node->data.param_decl.name, g->builtin_types.entry_invalid,
...@@ -4754,36 +4758,7 @@ static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import...@@ -4754,36 +4758,7 @@ static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import
47544758
4755 if (const_val->ok) {4759 if (const_val->ok) {
4756 if (invoke_type_entry->id == TypeTableEntryIdMetaType) {4760 if (invoke_type_entry->id == TypeTableEntryIdMetaType) {
4757 if (fn_ref_expr->type == NodeTypeFieldAccessExpr) {4761 return analyze_cast_expr(g, import, context, node);
4758 TypeTableEntry *child_type = resolve_type(g, fn_ref_expr);
4759
4760 if (child_type->id == TypeTableEntryIdInvalid) {
4761 return g->builtin_types.entry_invalid;
4762 } else if (child_type->id == TypeTableEntryIdStruct) {
4763 Buf *field_name = &fn_ref_expr->data.field_access_expr.field_name;
4764 BlockContext *container_block_context = get_container_block_context(child_type);
4765 auto entry = container_block_context->decl_table.maybe_get(field_name);
4766 AstNode *decl_node = entry ? entry->value : nullptr;
4767 if (decl_node && decl_node->type == NodeTypeFnProto) {
4768 bool pointer_only = false;
4769 resolve_top_level_decl(g, decl_node, pointer_only);
4770
4771 FnTableEntry *fn_entry = decl_node->data.fn_proto.fn_table_entry;
4772 assert(fn_entry);
4773 return analyze_fn_call_raw(g, import, context, expected_type, node, fn_entry, nullptr);
4774 } else {
4775 add_node_error(g, node,
4776 buf_sprintf("struct '%s' has no function called '%s'",
4777 buf_ptr(&child_type->name), buf_ptr(field_name)));
4778 return g->builtin_types.entry_invalid;
4779 }
4780 } else {
4781 add_node_error(g, fn_ref_expr, buf_sprintf("member reference base type not struct or enum"));
4782 return g->builtin_types.entry_invalid;
4783 }
4784 } else {
4785 return analyze_cast_expr(g, import, context, node);
4786 }
4787 } else if (invoke_type_entry->id == TypeTableEntryIdFn) {4762 } else if (invoke_type_entry->id == TypeTableEntryIdFn) {
4788 AstNode *struct_node;4763 AstNode *struct_node;
4789 if (fn_ref_expr->type == NodeTypeFieldAccessExpr &&4764 if (fn_ref_expr->type == NodeTypeFieldAccessExpr &&
...@@ -5120,7 +5095,7 @@ static TypeTableEntry *analyze_switch_expr(CodeGen *g, ImportTableEntry *import,...@@ -5120,7 +5095,7 @@ static TypeTableEntry *analyze_switch_expr(CodeGen *g, ImportTableEntry *import,
5120 ConstExprValue *const_val = &get_resolved_expr(item_node)->const_val;5095 ConstExprValue *const_val = &get_resolved_expr(item_node)->const_val;
5121 if (!const_val->ok) {5096 if (!const_val->ok) {
5122 add_node_error(g, item_node,5097 add_node_error(g, item_node,
5123 buf_sprintf("unable to resolve constant expression"));5098 buf_sprintf("unable to evaluate constant expression"));
5124 any_errors = true;5099 any_errors = true;
5125 }5100 }
5126 }5101 }
test/other.zig+1
...@@ -3,3 +3,4 @@ pub enum APubEnum {...@@ -3,3 +3,4 @@ pub enum APubEnum {
3 Two,3 Two,
4 Three,4 Three,
5}5}
6pub const size_t = u64;
test/run_tests.cpp+10-1
...@@ -1128,7 +1128,7 @@ fn foo(x: i32)(y: i32) -> i32 { return x + y; }...@@ -1128,7 +1128,7 @@ fn foo(x: i32)(y: i32) -> i32 { return x + y; }
1128fn test1(a: i32, b: i32) -> i32 {1128fn test1(a: i32, b: i32) -> i32 {
1129 return foo(a)(b);1129 return foo(a)(b);
1130}1130}
1131 )SOURCE", 1, ".tmp_source.zig:4:16: error: unable to resolve constant expression");1131 )SOURCE", 1, ".tmp_source.zig:4:16: error: unable to evaluate constant expression");
11321132
1133 add_compile_fail_case("goto jumping into block", R"SOURCE(1133 add_compile_fail_case("goto jumping into block", R"SOURCE(
1134fn f() {1134fn f() {
...@@ -1200,6 +1200,15 @@ struct Foo {...@@ -1200,6 +1200,15 @@ struct Foo {
1200const a = Foo {.x = get_it()};1200const a = Foo {.x = get_it()};
1201extern fn get_it() -> i32;1201extern fn get_it() -> i32;
1202 )SOURCE", 1, ".tmp_source.zig:5:27: error: unable to evaluate constant expression");1202 )SOURCE", 1, ".tmp_source.zig:5:27: error: unable to evaluate constant expression");
1203
1204 add_compile_fail_case("non-const expression function call with struct return value outside function", R"SOURCE(
1205struct Foo {
1206 x: i32,
1207}
1208const a = get_it();
1209#static_eval_enable(false)
1210fn get_it() -> Foo { Foo {.x = 13} }
1211 )SOURCE", 1, ".tmp_source.zig:5:17: error: unable to evaluate constant expression");
1203}1212}
12041213
1205//////////////////////////////////////////////////////////////////////////////1214//////////////////////////////////////////////////////////////////////////////
test/self_hosted.zig+6
...@@ -1252,3 +1252,9 @@ fn pub_enum() {...@@ -1252,3 +1252,9 @@ fn pub_enum() {
1252fn pub_enum_test(foo: other.APubEnum) {1252fn pub_enum_test(foo: other.APubEnum) {
1253 assert(foo == other.APubEnum.Two);1253 assert(foo == other.APubEnum.Two);
1254}1254}
1255
1256
1257#attribute("test")
1258fn cast_with_imported_symbol() {
1259 assert(other.size_t(42) == 42);
1260}