aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ir.cpp32
-rw-r--r--test/compile_errors.zig15
2 files changed, 42 insertions, 5 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index c572e3c885..de4543df4e 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -356,6 +356,28 @@ static void ir_ref_var(ZigVar *var) {
var->ref_count += 1;
}
+ZigType *ir_analyze_type_expr(IrAnalyze *ira, Scope *scope, AstNode *node) {
+ ConstExprValue *result = ir_eval_const_value( ira->codegen
+ , scope
+ , node
+ , ira->codegen->builtin_types.entry_type
+ , ira->new_irb.exec->backward_branch_count
+ , ira->new_irb.exec->backward_branch_quota
+ , nullptr
+ , nullptr
+ , node
+ , nullptr
+ , ira->new_irb.exec
+ , nullptr
+ );
+
+ if (type_is_invalid(result->type))
+ return ira->codegen->builtin_types.entry_invalid;
+
+ assert(result->special != ConstValSpecialRuntime);
+ return result->data.x_type;
+}
+
static IrBasicBlock *ir_create_basic_block(IrBuilder *irb, Scope *scope, const char *name_hint) {
IrBasicBlock *result = allocate<IrBasicBlock>(1);
result->scope = scope;
@@ -13875,7 +13897,7 @@ static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node
IrInstruction *casted_arg;
if (param_decl_node->data.param_decl.var_token == nullptr) {
AstNode *param_type_node = param_decl_node->data.param_decl.type;
- ZigType *param_type = analyze_type_expr(ira->codegen, *exec_scope, param_type_node);
+ ZigType *param_type = ir_analyze_type_expr(ira, *exec_scope, param_type_node);
if (type_is_invalid(param_type))
return false;
@@ -13915,7 +13937,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
} else {
if (param_decl_node->data.param_decl.var_token == nullptr) {
AstNode *param_type_node = param_decl_node->data.param_decl.type;
- ZigType *param_type = analyze_type_expr(ira->codegen, *child_scope, param_type_node);
+ ZigType *param_type = ir_analyze_type_expr(ira, *child_scope, param_type_node);
if (type_is_invalid(param_type))
return false;
@@ -14296,7 +14318,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
}
AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type;
- ZigType *specified_return_type = analyze_type_expr(ira->codegen, exec_scope, return_type_node);
+ ZigType *specified_return_type = ir_analyze_type_expr(ira, exec_scope, return_type_node);
if (type_is_invalid(specified_return_type))
return ira->codegen->invalid_instruction;
ZigType *return_type;
@@ -14532,7 +14554,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
if (fn_proto_node->data.fn_proto.return_var_token == nullptr) {
AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type;
- ZigType *specified_return_type = analyze_type_expr(ira->codegen, impl_fn->child_scope, return_type_node);
+ ZigType *specified_return_type = ir_analyze_type_expr(ira, impl_fn->child_scope, return_type_node);
if (type_is_invalid(specified_return_type))
return ira->codegen->invalid_instruction;
if (fn_proto_node->data.fn_proto.auto_err_set) {
@@ -14559,7 +14581,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
if (call_instruction->is_async) {
AstNode *async_allocator_type_node = fn_proto_node->data.fn_proto.async_allocator_type;
if (async_allocator_type_node != nullptr) {
- ZigType *async_allocator_type = analyze_type_expr(ira->codegen, impl_fn->child_scope, async_allocator_type_node);
+ ZigType *async_allocator_type = ir_analyze_type_expr(ira, impl_fn->child_scope, async_allocator_type_node);
if (type_is_invalid(async_allocator_type))
return ira->codegen->invalid_instruction;
inst_fn_type_id.async_allocator_type = async_allocator_type;
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index a31605b02a..0d30bd7175 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -3,6 +3,21 @@ const builtin = @import("builtin");
pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
+ "Generic function where return type is self-referenced",
+ \\fn Foo(comptime T: type) Foo(T) {
+ \\ return struct{ x: T };
+ \\}
+ \\export fn entry() void {
+ \\ const t = Foo(u32) {
+ \\ .x = 1
+ \\ };
+ \\}
+ ,
+ "tmp.zig:1:29: error: evaluation exceeded 1000 backwards branches",
+ "tmp.zig:1:29: note: called from here",
+ );
+
+ cases.add(
"@ptrToInt 0 to non optional pointer",
\\export fn entry() void {
\\ var b = @intToPtr(*i32, 0);