From b1f8b53d208723663f14b54d7f4863a54f999553 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Tue, 16 Jul 2019 16:20:54 -0400
Subject: rename internal names regarding `usingnamespace`
---
src/parser.cpp | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
(limited to 'src/parser.cpp')
diff --git a/src/parser.cpp b/src/parser.cpp
index 25541d5351..0783d4ec10 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -671,14 +671,14 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod) {
return res;
}
- Token *use = eat_token_if(pc, TokenIdKeywordUsingNamespace);
- if (use != nullptr) {
+ Token *usingnamespace = eat_token_if(pc, TokenIdKeywordUsingNamespace);
+ if (usingnamespace != nullptr) {
AstNode *expr = ast_expect(pc, ast_parse_expr);
expect_token(pc, TokenIdSemicolon);
- AstNode *res = ast_create_node(pc, NodeTypeUse, use);
- res->data.use.visib_mod = visib_mod;
- res->data.use.expr = expr;
+ AstNode *res = ast_create_node(pc, NodeTypeUse, usingnamespace);
+ res->data.using_namespace.visib_mod = visib_mod;
+ res->data.using_namespace.expr = expr;
return res;
}
@@ -2939,7 +2939,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
visit_field(&node->data.unwrap_optional.expr, visit, context);
break;
case NodeTypeUse:
- visit_field(&node->data.use.expr, visit, context);
+ visit_field(&node->data.using_namespace.expr, visit, context);
break;
case NodeTypeBoolLiteral:
// none
--
cgit v1.2.3
From af8661405b908c0abfc191501a8ad1a59a54e86a Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Fri, 19 Jul 2019 16:56:44 -0400
Subject: fix usingnamespace
It used to be that usingnamespace was only allowed at top level. This
made it OK to put the state inside the AST node data structure. However,
now usingnamespace can occur inside any aggregate data structure, and
therefore the state must be in the TopLevelDeclaration rather than in
the AST node.
There were two other problems with the usingnamespace implementation:
* It was passing the wrong destination ScopeDecl, so it could cause an
incorrect error such as "import of file outside package path".
* When doing `usingnamespace` on a file that already had
`pub usingnamespace` in it would "steal" the usingnamespace, causing
incorrect "use of undeclared identifier" errors in the target file.
closes #2632
closes #2580
---
src/all_types.hpp | 16 +-
src/analyze.cpp | 265 +++++++++++++++++---------------
src/analyze.hpp | 2 -
src/ast_render.cpp | 8 +-
src/ir.cpp | 3 +-
src/parser.cpp | 4 +-
test/compile_errors.zig | 2 +-
test/stage1/behavior.zig | 1 +
test/stage1/behavior/usingnamespace.zig | 14 ++
9 files changed, 170 insertions(+), 145 deletions(-)
create mode 100644 test/stage1/behavior/usingnamespace.zig
(limited to 'src/parser.cpp')
diff --git a/src/all_types.hpp b/src/all_types.hpp
index 79ade39ef7..a6b2bc51c3 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -366,6 +366,7 @@ enum TldId {
TldIdFn,
TldIdContainer,
TldIdCompTime,
+ TldIdUsingNamespace,
};
enum TldResolution {
@@ -413,6 +414,12 @@ struct TldCompTime {
Tld base;
};
+struct TldUsingNamespace {
+ Tld base;
+
+ ConstExprValue *using_namespace_value;
+};
+
struct TypeEnumField {
Buf *name;
BigInt value;
@@ -453,7 +460,7 @@ enum NodeType {
NodeTypeFieldAccessExpr,
NodeTypePtrDeref,
NodeTypeUnwrapOptional,
- NodeTypeUse,
+ NodeTypeUsingNamespace,
NodeTypeBoolLiteral,
NodeTypeNullLiteral,
NodeTypeUndefinedLiteral,
@@ -715,9 +722,6 @@ struct AstNodeArrayType {
struct AstNodeUsingNamespace {
VisibMod visib_mod;
AstNode *expr;
-
- TldResolution resolution;
- ConstExprValue *using_namespace_value;
};
struct AstNodeIfBoolExpr {
@@ -1745,8 +1749,6 @@ struct CodeGen {
ZigList resolve_queue;
size_t resolve_queue_index;
- ZigList use_queue;
- size_t use_queue_index;
ZigList timing_events;
ZigList tld_ref_source_node_stack;
ZigList inline_fns;
@@ -2005,7 +2007,7 @@ struct ScopeDecls {
Scope base;
HashMap decl_table;
- ZigList use_decls;
+ ZigList use_decls;
AstNode *safety_set_node;
AstNode *fast_math_set_node;
ZigType *import;
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 797451c8f8..de4d64f5d6 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -28,6 +28,8 @@ static Error ATTRIBUTE_MUST_USE resolve_union_zero_bits(CodeGen *g, ZigType *uni
static Error ATTRIBUTE_MUST_USE resolve_union_alignment(CodeGen *g, ZigType *union_type);
static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry);
static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status);
+static void preview_use_decl(CodeGen *g, TldUsingNamespace *using_namespace, ScopeDecls *dest_decls_scope);
+static void resolve_use_decl(CodeGen *g, TldUsingNamespace *tld_using_namespace, ScopeDecls *dest_decls_scope);
static bool is_top_level_struct(ZigType *import) {
return import->id == ZigTypeIdStruct && import->data.structure.root_struct != nullptr;
@@ -2854,6 +2856,8 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
add_node_error(g, tld->source_node, buf_sprintf("non-extern function has no body"));
return;
}
+ } else if (tld->id == TldIdUsingNamespace) {
+ g->resolve_queue.append(tld);
}
if (is_export) {
g->resolve_queue.append(tld);
@@ -2867,7 +2871,7 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
}
}
- {
+ if (tld->name != nullptr) {
auto entry = decls_scope->decl_table.put_unique(tld->name, tld);
if (entry) {
Tld *other_tld = entry->value;
@@ -2875,9 +2879,7 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
add_error_note(g, msg, other_tld->source_node, buf_sprintf("previous definition is here"));
return;
}
- }
- {
ZigType *type;
if (get_primitive_type(g, tld->name, &type) != ErrorPrimitiveTypeNotFound) {
add_node_error(g, tld->source_node,
@@ -2977,12 +2979,14 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
break;
}
- case NodeTypeUse:
- {
- g->use_queue.append(node);
- decls_scope->use_decls.append(node);
- break;
- }
+ case NodeTypeUsingNamespace: {
+ VisibMod visib_mod = node->data.using_namespace.visib_mod;
+ TldUsingNamespace *tld_using_namespace = allocate(1);
+ init_tld(&tld_using_namespace->base, TldIdUsingNamespace, nullptr, visib_mod, node, &decls_scope->base);
+ add_top_level_decl(g, decls_scope, &tld_using_namespace->base);
+ decls_scope->use_decls.append(tld_using_namespace);
+ break;
+ }
case NodeTypeTestDecl:
preview_test_decl(g, node, decls_scope);
break;
@@ -3266,6 +3270,117 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
g->global_vars.append(tld_var);
}
+static void add_symbols_from_container(CodeGen *g, TldUsingNamespace *src_using_namespace,
+ TldUsingNamespace *dst_using_namespace, ScopeDecls* dest_decls_scope)
+{
+ if (src_using_namespace->base.resolution == TldResolutionUnresolved ||
+ src_using_namespace->base.resolution == TldResolutionResolving)
+ {
+ assert(src_using_namespace->base.parent_scope->id == ScopeIdDecls);
+ ScopeDecls *src_decls_scope = (ScopeDecls *)src_using_namespace->base.parent_scope;
+ preview_use_decl(g, src_using_namespace, src_decls_scope);
+ if (src_using_namespace != dst_using_namespace) {
+ resolve_use_decl(g, src_using_namespace, src_decls_scope);
+ }
+ }
+
+ ConstExprValue *use_expr = src_using_namespace->using_namespace_value;
+ if (type_is_invalid(use_expr->type)) {
+ dest_decls_scope->any_imports_failed = true;
+ return;
+ }
+
+ dst_using_namespace->base.resolution = TldResolutionOk;
+
+ assert(use_expr->special != ConstValSpecialRuntime);
+
+ // The source scope for the imported symbols
+ ScopeDecls *src_scope = get_container_scope(use_expr->data.x_type);
+ // The top-level container where the symbols are defined, it's used in the
+ // loop below in order to exclude the ones coming from an import statement
+ ZigType *src_import = get_scope_import(&src_scope->base);
+ assert(src_import != nullptr);
+
+ if (src_scope->any_imports_failed) {
+ dest_decls_scope->any_imports_failed = true;
+ }
+
+ auto it = src_scope->decl_table.entry_iterator();
+ for (;;) {
+ auto *entry = it.next();
+ if (!entry)
+ break;
+
+ Buf *target_tld_name = entry->key;
+ Tld *target_tld = entry->value;
+
+ if (target_tld->visib_mod == VisibModPrivate) {
+ continue;
+ }
+
+ if (target_tld->import != src_import) {
+ continue;
+ }
+
+ auto existing_entry = dest_decls_scope->decl_table.put_unique(target_tld_name, target_tld);
+ if (existing_entry) {
+ Tld *existing_decl = existing_entry->value;
+ if (existing_decl != target_tld) {
+ ErrorMsg *msg = add_node_error(g, dst_using_namespace->base.source_node,
+ buf_sprintf("import of '%s' overrides existing definition",
+ buf_ptr(target_tld_name)));
+ add_error_note(g, msg, existing_decl->source_node, buf_sprintf("previous definition here"));
+ add_error_note(g, msg, target_tld->source_node, buf_sprintf("imported definition here"));
+ }
+ }
+ }
+
+ for (size_t i = 0; i < src_scope->use_decls.length; i += 1) {
+ TldUsingNamespace *tld_using_namespace = src_scope->use_decls.at(i);
+ if (tld_using_namespace->base.visib_mod != VisibModPrivate)
+ add_symbols_from_container(g, tld_using_namespace, dst_using_namespace, dest_decls_scope);
+ }
+}
+
+static void resolve_use_decl(CodeGen *g, TldUsingNamespace *tld_using_namespace, ScopeDecls *dest_decls_scope) {
+ if (tld_using_namespace->base.resolution == TldResolutionOk ||
+ tld_using_namespace->base.resolution == TldResolutionInvalid)
+ {
+ return;
+ }
+ add_symbols_from_container(g, tld_using_namespace, tld_using_namespace, dest_decls_scope);
+}
+
+static void preview_use_decl(CodeGen *g, TldUsingNamespace *using_namespace, ScopeDecls *dest_decls_scope) {
+ if (using_namespace->base.resolution == TldResolutionOk ||
+ using_namespace->base.resolution == TldResolutionInvalid)
+ {
+ return;
+ }
+
+ using_namespace->base.resolution = TldResolutionResolving;
+ assert(using_namespace->base.source_node->type == NodeTypeUsingNamespace);
+ ConstExprValue *result = analyze_const_value(g, &dest_decls_scope->base,
+ using_namespace->base.source_node->data.using_namespace.expr, g->builtin_types.entry_type, nullptr);
+ using_namespace->using_namespace_value = result;
+
+ if (type_is_invalid(result->type)) {
+ dest_decls_scope->any_imports_failed = true;
+ using_namespace->base.resolution = TldResolutionInvalid;
+ using_namespace->using_namespace_value = &g->invalid_instruction->value;
+ return;
+ }
+
+ if (!is_container(result->data.x_type)) {
+ add_node_error(g, using_namespace->base.source_node,
+ buf_sprintf("expected struct, enum, or union; found '%s'", buf_ptr(&result->data.x_type->name)));
+ dest_decls_scope->any_imports_failed = true;
+ using_namespace->base.resolution = TldResolutionInvalid;
+ using_namespace->using_namespace_value = &g->invalid_instruction->value;
+ return;
+ }
+}
+
void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node) {
if (tld->resolution != TldResolutionUnresolved)
return;
@@ -3299,6 +3414,14 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node) {
resolve_decl_comptime(g, tld_comptime);
break;
}
+ case TldIdUsingNamespace: {
+ TldUsingNamespace *tld_using_namespace = (TldUsingNamespace *)tld;
+ assert(tld_using_namespace->base.parent_scope->id == ScopeIdDecls);
+ ScopeDecls *dest_decls_scope = (ScopeDecls *)tld_using_namespace->base.parent_scope;
+ preview_use_decl(g, tld_using_namespace, dest_decls_scope);
+ resolve_use_decl(g, tld_using_namespace, dest_decls_scope);
+ break;
+ }
}
tld->resolution = TldResolutionOk;
@@ -3308,10 +3431,10 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node) {
Tld *find_container_decl(CodeGen *g, ScopeDecls *decls_scope, Buf *name) {
// resolve all the using_namespace decls
for (size_t i = 0; i < decls_scope->use_decls.length; i += 1) {
- AstNode *use_decl_node = decls_scope->use_decls.at(i);
- if (use_decl_node->data.using_namespace.resolution == TldResolutionUnresolved) {
- preview_use_decl(g, use_decl_node, decls_scope);
- resolve_use_decl(g, use_decl_node, decls_scope);
+ TldUsingNamespace *tld_using_namespace = decls_scope->use_decls.at(i);
+ if (tld_using_namespace->base.resolution == TldResolutionUnresolved) {
+ preview_use_decl(g, tld_using_namespace, decls_scope);
+ resolve_use_decl(g, tld_using_namespace, decls_scope);
}
}
@@ -3752,110 +3875,6 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {
analyze_fn_ir(g, fn_table_entry, return_type_node);
}
-static void add_symbols_from_container(CodeGen *g, AstNode *src_use_node, AstNode *dst_use_node, ScopeDecls* decls_scope) {
- if (src_use_node->data.using_namespace.resolution == TldResolutionUnresolved) {
- preview_use_decl(g, src_use_node, decls_scope);
- }
-
- ConstExprValue *use_expr = src_use_node->data.using_namespace.using_namespace_value;
- if (type_is_invalid(use_expr->type)) {
- decls_scope->any_imports_failed = true;
- return;
- }
-
- dst_use_node->data.using_namespace.resolution = TldResolutionOk;
-
- assert(use_expr->special != ConstValSpecialRuntime);
-
- // The source struct for the imported symbols
- ZigType *src_ty = use_expr->data.x_type;
- assert(src_ty);
-
- if (!is_container(src_ty)) {
- add_node_error(g, dst_use_node,
- buf_sprintf("expected struct, enum, or union; found '%s'", buf_ptr(&src_ty->name)));
- decls_scope->any_imports_failed = true;
- return;
- }
-
- // The source scope for the imported symbols
- ScopeDecls *src_scope = get_container_scope(src_ty);
- // The top-level container where the symbols are defined, it's used in the
- // loop below in order to exclude the ones coming from an import statement
- ZigType *src_import = get_scope_import(&src_scope->base);
- assert(src_import != nullptr);
-
- if (src_scope->any_imports_failed) {
- decls_scope->any_imports_failed = true;
- }
-
- auto it = src_scope->decl_table.entry_iterator();
- for (;;) {
- auto *entry = it.next();
- if (!entry)
- break;
-
- Buf *target_tld_name = entry->key;
- Tld *target_tld = entry->value;
-
- if (target_tld->visib_mod == VisibModPrivate) {
- continue;
- }
-
- if (target_tld->import != src_import) {
- continue;
- }
-
- auto existing_entry = decls_scope->decl_table.put_unique(target_tld_name, target_tld);
- if (existing_entry) {
- Tld *existing_decl = existing_entry->value;
- if (existing_decl != target_tld) {
- ErrorMsg *msg = add_node_error(g, dst_use_node,
- buf_sprintf("import of '%s' overrides existing definition",
- buf_ptr(target_tld_name)));
- add_error_note(g, msg, existing_decl->source_node, buf_sprintf("previous definition here"));
- add_error_note(g, msg, target_tld->source_node, buf_sprintf("imported definition here"));
- }
- }
- }
-
- for (size_t i = 0; i < src_scope->use_decls.length; i += 1) {
- AstNode *use_decl_node = src_scope->use_decls.at(i);
- if (use_decl_node->data.using_namespace.visib_mod != VisibModPrivate)
- add_symbols_from_container(g, use_decl_node, dst_use_node, decls_scope);
- }
-}
-
-void resolve_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {
- assert(node->type == NodeTypeUse);
-
- if (node->data.using_namespace.resolution == TldResolutionOk ||
- node->data.using_namespace.resolution == TldResolutionInvalid)
- {
- return;
- }
- add_symbols_from_container(g, node, node, decls_scope);
-}
-
-void preview_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {
- assert(node->type == NodeTypeUse);
-
- if (node->data.using_namespace.resolution == TldResolutionOk ||
- node->data.using_namespace.resolution == TldResolutionInvalid)
- {
- return;
- }
-
- node->data.using_namespace.resolution = TldResolutionResolving;
- ConstExprValue *result = analyze_const_value(g, &decls_scope->base,
- node->data.using_namespace.expr, g->builtin_types.entry_type, nullptr);
-
- if (type_is_invalid(result->type))
- decls_scope->any_imports_failed = true;
-
- node->data.using_namespace.using_namespace_value = result;
-}
-
ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Buf *source_code,
SourceKind source_kind)
{
@@ -3975,18 +3994,8 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu
void semantic_analyze(CodeGen *g) {
while (g->resolve_queue_index < g->resolve_queue.length ||
- g->fn_defs_index < g->fn_defs.length ||
- g->use_queue_index < g->use_queue.length)
+ g->fn_defs_index < g->fn_defs.length)
{
- for (; g->use_queue_index < g->use_queue.length; g->use_queue_index += 1) {
- AstNode *use_decl_node = g->use_queue.at(g->use_queue_index);
- // Get the top-level scope where `using_namespace` is used
- ScopeDecls *decls_scope = get_container_scope(use_decl_node->owner);
- if (use_decl_node->data.using_namespace.resolution == TldResolutionUnresolved) {
- preview_use_decl(g, use_decl_node, decls_scope);
- resolve_use_decl(g, use_decl_node, decls_scope);
- }
- }
for (; g->resolve_queue_index < g->resolve_queue.length; g->resolve_queue_index += 1) {
Tld *tld = g->resolve_queue.at(g->resolve_queue_index);
AstNode *source_node = nullptr;
diff --git a/src/analyze.hpp b/src/analyze.hpp
index a6ad92110e..b9e9f2df7d 100644
--- a/src/analyze.hpp
+++ b/src/analyze.hpp
@@ -86,8 +86,6 @@ bool is_array_ref(ZigType *type_entry);
bool is_container_ref(ZigType *type_entry);
bool is_valid_vector_elem_type(ZigType *elem_type);
void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node);
-void preview_use_decl(CodeGen *g, AstNode *node, ScopeDecls* decls_scope);
-void resolve_use_decl(CodeGen *g, AstNode *node, ScopeDecls* decls_scope);
ZigFn *scope_fn_entry(Scope *scope);
ZigPackage *scope_package(Scope *scope);
ZigType *get_scope_import(Scope *scope);
diff --git a/src/ast_render.cpp b/src/ast_render.cpp
index 154803f884..fe131ab65f 100644
--- a/src/ast_render.cpp
+++ b/src/ast_render.cpp
@@ -193,8 +193,8 @@ static const char *node_type_str(NodeType node_type) {
return "Symbol";
case NodeTypePrefixOpExpr:
return "PrefixOpExpr";
- case NodeTypeUse:
- return "Use";
+ case NodeTypeUsingNamespace:
+ return "UsingNamespace";
case NodeTypeBoolLiteral:
return "BoolLiteral";
case NodeTypeNullLiteral:
@@ -791,7 +791,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
AstNode *decls_node = node->data.container_decl.decls.at(decl_i);
render_node_grouped(ar, decls_node);
- if (decls_node->type == NodeTypeUse ||
+ if (decls_node->type == NodeTypeUsingNamespace ||
decls_node->type == NodeTypeVariableDeclaration ||
decls_node->type == NodeTypeFnProto)
{
@@ -1170,7 +1170,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
case NodeTypeParamDecl:
case NodeTypeTestDecl:
case NodeTypeStructField:
- case NodeTypeUse:
+ case NodeTypeUsingNamespace:
zig_panic("TODO more ast rendering");
}
}
diff --git a/src/ir.cpp b/src/ir.cpp
index 579875dc3c..be7a8e2e51 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -8430,7 +8430,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
switch (node->type) {
case NodeTypeStructValueField:
case NodeTypeParamDecl:
- case NodeTypeUse:
+ case NodeTypeUsingNamespace:
case NodeTypeSwitchProng:
case NodeTypeSwitchRange:
case NodeTypeStructField:
@@ -17847,6 +17847,7 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_
switch (tld->id) {
case TldIdContainer:
case TldIdCompTime:
+ case TldIdUsingNamespace:
zig_unreachable();
case TldIdVar:
{
diff --git a/src/parser.cpp b/src/parser.cpp
index 0783d4ec10..fe1f89ac92 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -676,7 +676,7 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod) {
AstNode *expr = ast_expect(pc, ast_parse_expr);
expect_token(pc, TokenIdSemicolon);
- AstNode *res = ast_create_node(pc, NodeTypeUse, usingnamespace);
+ AstNode *res = ast_create_node(pc, NodeTypeUsingNamespace, usingnamespace);
res->data.using_namespace.visib_mod = visib_mod;
res->data.using_namespace.expr = expr;
return res;
@@ -2938,7 +2938,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
case NodeTypeUnwrapOptional:
visit_field(&node->data.unwrap_optional.expr, visit, context);
break;
- case NodeTypeUse:
+ case NodeTypeUsingNamespace:
visit_field(&node->data.using_namespace.expr, visit, context);
break;
case NodeTypeBoolLiteral:
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index fd365235d8..40ce8d304b 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -234,7 +234,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"usingnamespace with wrong type",
- \\use void;
+ \\usingnamespace void;
,
"tmp.zig:1:1: error: expected struct, enum, or union; found 'void'",
);
diff --git a/test/stage1/behavior.zig b/test/stage1/behavior.zig
index db8fdcf368..71af5586ed 100644
--- a/test/stage1/behavior.zig
+++ b/test/stage1/behavior.zig
@@ -93,6 +93,7 @@ comptime {
_ = @import("behavior/undefined.zig");
_ = @import("behavior/underscore.zig");
_ = @import("behavior/union.zig");
+ _ = @import("behavior/usingnamespace.zig");
_ = @import("behavior/var_args.zig");
_ = @import("behavior/vector.zig");
_ = @import("behavior/void.zig");
diff --git a/test/stage1/behavior/usingnamespace.zig b/test/stage1/behavior/usingnamespace.zig
new file mode 100644
index 0000000000..fb45a9392d
--- /dev/null
+++ b/test/stage1/behavior/usingnamespace.zig
@@ -0,0 +1,14 @@
+const std = @import("std");
+
+fn Foo(comptime T: type) type {
+ return struct {
+ usingnamespace T;
+ };
+}
+
+test "usingnamespace inside a generic struct" {
+ const std2 = Foo(std);
+ const testing2 = Foo(std.testing);
+ std2.testing.expect(true);
+ testing2.expect(true);
+}
--
cgit v1.2.3
From 54e716afdcb0609cfc42229ad925e6dc9b07a66f Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 27 Jun 2019 23:40:36 -0400
Subject: remove coroutines implementation and promise type
---
src-self-hosted/main.zig | 16 +-
src/all_types.hpp | 191 -----
src/analyze.cpp | 172 +---
src/analyze.hpp | 4 -
src/ast_render.cpp | 19 +-
src/codegen.cpp | 674 +---------------
src/ir.cpp | 1539 +-----------------------------------
src/ir_print.cpp | 190 +----
src/parser.cpp | 32 -
src/tokenizer.cpp | 2 -
src/tokenizer.hpp | 1 -
std/fmt.zig | 3 -
std/hash_map.zig | 2 +-
std/meta.zig | 4 +-
std/testing.zig | 1 -
test/stage1/behavior.zig | 6 +-
test/stage1/behavior/type_info.zig | 20 +-
17 files changed, 62 insertions(+), 2814 deletions(-)
(limited to 'src/parser.cpp')
diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig
index 8917809533..63ac47147d 100644
--- a/src-self-hosted/main.zig
+++ b/src-self-hosted/main.zig
@@ -466,7 +466,7 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co
comp.link_objects = link_objects;
comp.start();
- const process_build_events_handle = try async processBuildEvents(comp, color);
+ // TODO const process_build_events_handle = try async processBuildEvents(comp, color);
defer cancel process_build_events_handle;
loop.run();
}
@@ -578,7 +578,7 @@ fn cmdLibC(allocator: *Allocator, args: []const []const u8) !void {
var zig_compiler = try ZigCompiler.init(&loop);
defer zig_compiler.deinit();
- const handle = try async findLibCAsync(&zig_compiler);
+ // TODO const handle = try async findLibCAsync(&zig_compiler);
defer cancel handle;
loop.run();
@@ -663,12 +663,12 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {
defer loop.deinit();
var result: FmtError!void = undefined;
- const main_handle = try async asyncFmtMainChecked(
- &result,
- &loop,
- &flags,
- color,
- );
+ // TODO const main_handle = try async asyncFmtMainChecked(
+ // TODO &result,
+ // TODO &loop,
+ // TODO &flags,
+ // TODO color,
+ // TODO );
defer cancel main_handle;
loop.run();
return result;
diff --git a/src/all_types.hpp b/src/all_types.hpp
index a6b2bc51c3..7fe035ad1c 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -70,17 +70,6 @@ struct IrExecutable {
Scope *begin_scope;
ZigList tld_list;
- IrInstruction *coro_handle;
- IrInstruction *atomic_state_field_ptr; // this one is shared and in the promise
- IrInstruction *coro_result_ptr_field_ptr;
- IrInstruction *coro_result_field_ptr;
- IrInstruction *await_handle_var_ptr; // this one is where we put the one we extracted from the promise
- IrBasicBlock *coro_early_final;
- IrBasicBlock *coro_normal_final;
- IrBasicBlock *coro_suspend_block;
- IrBasicBlock *coro_final_cleanup_block;
- ZigVar *coro_allocator_var;
-
bool invalid;
bool is_inline;
bool is_generic_instantiation;
@@ -489,7 +478,6 @@ enum NodeType {
NodeTypeResume,
NodeTypeAwaitExpr,
NodeTypeSuspend,
- NodeTypePromiseType,
NodeTypeEnumLiteral,
};
@@ -522,7 +510,6 @@ struct AstNodeFnProto {
AstNode *section_expr;
bool auto_err_set;
- AstNode *async_allocator_type;
};
struct AstNodeFnDef {
@@ -657,7 +644,6 @@ struct AstNodeFnCallExpr {
bool is_builtin;
bool is_async;
bool seen; // used by @compileLog
- AstNode *async_allocator;
};
struct AstNodeArrayAccessExpr {
@@ -949,10 +935,6 @@ struct AstNodeSuspend {
AstNode *block;
};
-struct AstNodePromiseType {
- AstNode *payload_type; // can be NULL
-};
-
struct AstNodeEnumLiteral {
Token *period;
Token *identifier;
@@ -1018,7 +1000,6 @@ struct AstNode {
AstNodeResumeExpr resume_expr;
AstNodeAwaitExpr await_expr;
AstNodeSuspend suspend;
- AstNodePromiseType promise_type;
AstNodeEnumLiteral enum_literal;
} data;
};
@@ -1047,7 +1028,6 @@ struct FnTypeId {
bool is_var_args;
CallingConvention cc;
uint32_t alignment;
- ZigType *async_allocator_type;
};
uint32_t fn_type_id_hash(FnTypeId*);
@@ -1241,11 +1221,6 @@ struct ZigTypeBoundFn {
ZigType *fn_type;
};
-struct ZigTypePromise {
- // null if `promise` instead of `promise->T`
- ZigType *result_type;
-};
-
struct ZigTypeVector {
// The type must be a pointer, integer, or float
ZigType *elem_type;
@@ -1276,7 +1251,6 @@ enum ZigTypeId {
ZigTypeIdBoundFn,
ZigTypeIdArgTuple,
ZigTypeIdOpaque,
- ZigTypeIdPromise,
ZigTypeIdVector,
ZigTypeIdEnumLiteral,
};
@@ -1314,7 +1288,6 @@ struct ZigType {
ZigTypeUnion unionation;
ZigTypeFn fn;
ZigTypeBoundFn bound_fn;
- ZigTypePromise promise;
ZigTypeVector vector;
ZigTypeOpaque opaque;
} data;
@@ -1322,8 +1295,6 @@ struct ZigType {
// use these fields to make sure we don't duplicate type table entries for the same type
ZigType *pointer_parent[2]; // [0 - mut, 1 - const]
ZigType *optional_parent;
- ZigType *promise_parent;
- ZigType *promise_frame_parent;
// If we generate a constant name value for this type, we memoize it here.
// The type of this is array
ConstExprValue *cached_const_name_val;
@@ -1709,20 +1680,6 @@ struct CodeGen {
LLVMValueRef trap_fn_val;
LLVMValueRef return_address_fn_val;
LLVMValueRef frame_address_fn_val;
- LLVMValueRef coro_destroy_fn_val;
- LLVMValueRef coro_id_fn_val;
- LLVMValueRef coro_alloc_fn_val;
- LLVMValueRef coro_size_fn_val;
- LLVMValueRef coro_begin_fn_val;
- LLVMValueRef coro_suspend_fn_val;
- LLVMValueRef coro_end_fn_val;
- LLVMValueRef coro_free_fn_val;
- LLVMValueRef coro_resume_fn_val;
- LLVMValueRef coro_save_fn_val;
- LLVMValueRef coro_promise_fn_val;
- LLVMValueRef coro_alloc_helper_fn_val;
- LLVMValueRef coro_frame_fn_val;
- LLVMValueRef merge_err_ret_traces_fn_val;
LLVMValueRef add_error_return_trace_addr_fn_val;
LLVMValueRef stacksave_fn_val;
LLVMValueRef stackrestore_fn_val;
@@ -1797,7 +1754,6 @@ struct CodeGen {
ZigType *entry_var;
ZigType *entry_global_error_set;
ZigType *entry_arg_tuple;
- ZigType *entry_promise;
ZigType *entry_enum_literal;
} builtin_types;
ZigType *align_amt_type;
@@ -1985,7 +1941,6 @@ enum ScopeId {
ScopeIdSuspend,
ScopeIdFnDef,
ScopeIdCompTime,
- ScopeIdCoroPrelude,
ScopeIdRuntime,
};
@@ -2128,12 +2083,6 @@ struct ScopeFnDef {
ZigFn *fn_entry;
};
-// This scope is created to indicate that the code in the scope
-// is auto-generated coroutine prelude stuff.
-struct ScopeCoroPrelude {
- Scope base;
-};
-
// synchronized with code in define_builtin_compile_vars
enum AtomicOrder {
AtomicOrderUnordered,
@@ -2231,7 +2180,6 @@ enum IrInstructionId {
IrInstructionIdSetRuntimeSafety,
IrInstructionIdSetFloatMode,
IrInstructionIdArrayType,
- IrInstructionIdPromiseType,
IrInstructionIdSliceType,
IrInstructionIdGlobalAsm,
IrInstructionIdAsm,
@@ -2329,26 +2277,10 @@ enum IrInstructionId {
IrInstructionIdErrorReturnTrace,
IrInstructionIdErrorUnion,
IrInstructionIdCancel,
- IrInstructionIdGetImplicitAllocator,
- IrInstructionIdCoroId,
- IrInstructionIdCoroAlloc,
- IrInstructionIdCoroSize,
- IrInstructionIdCoroBegin,
- IrInstructionIdCoroAllocFail,
- IrInstructionIdCoroSuspend,
- IrInstructionIdCoroEnd,
- IrInstructionIdCoroFree,
- IrInstructionIdCoroResume,
- IrInstructionIdCoroSave,
- IrInstructionIdCoroPromise,
- IrInstructionIdCoroAllocHelper,
IrInstructionIdAtomicRmw,
IrInstructionIdAtomicLoad,
- IrInstructionIdPromiseResultType,
- IrInstructionIdAwaitBookkeeping,
IrInstructionIdSaveErrRetAddr,
IrInstructionIdAddImplicitReturnType,
- IrInstructionIdMergeErrRetTraces,
IrInstructionIdMarkErrRetTracePtr,
IrInstructionIdErrSetCast,
IrInstructionIdToBytes,
@@ -2606,7 +2538,6 @@ struct IrInstructionCallSrc {
IrInstruction **args;
ResultLoc *result_loc;
- IrInstruction *async_allocator;
IrInstruction *new_stack;
FnInline fn_inline;
bool is_async;
@@ -2622,7 +2553,6 @@ struct IrInstructionCallGen {
IrInstruction **args;
IrInstruction *result_loc;
- IrInstruction *async_allocator;
IrInstruction *new_stack;
FnInline fn_inline;
bool is_async;
@@ -2743,12 +2673,6 @@ struct IrInstructionPtrType {
bool is_allow_zero;
};
-struct IrInstructionPromiseType {
- IrInstruction base;
-
- IrInstruction *payload_type;
-};
-
struct IrInstructionSliceType {
IrInstruction base;
@@ -3178,7 +3102,6 @@ struct IrInstructionFnProto {
IrInstruction **param_types;
IrInstruction *align_value;
IrInstruction *return_type;
- IrInstruction *async_allocator_type_value;
bool is_var_args;
};
@@ -3414,89 +3337,6 @@ struct IrInstructionCancel {
IrInstruction *target;
};
-enum ImplicitAllocatorId {
- ImplicitAllocatorIdArg,
- ImplicitAllocatorIdLocalVar,
-};
-
-struct IrInstructionGetImplicitAllocator {
- IrInstruction base;
-
- ImplicitAllocatorId id;
-};
-
-struct IrInstructionCoroId {
- IrInstruction base;
-
- IrInstruction *promise_ptr;
-};
-
-struct IrInstructionCoroAlloc {
- IrInstruction base;
-
- IrInstruction *coro_id;
-};
-
-struct IrInstructionCoroSize {
- IrInstruction base;
-};
-
-struct IrInstructionCoroBegin {
- IrInstruction base;
-
- IrInstruction *coro_id;
- IrInstruction *coro_mem_ptr;
-};
-
-struct IrInstructionCoroAllocFail {
- IrInstruction base;
-
- IrInstruction *err_val;
-};
-
-struct IrInstructionCoroSuspend {
- IrInstruction base;
-
- IrInstruction *save_point;
- IrInstruction *is_final;
-};
-
-struct IrInstructionCoroEnd {
- IrInstruction base;
-};
-
-struct IrInstructionCoroFree {
- IrInstruction base;
-
- IrInstruction *coro_id;
- IrInstruction *coro_handle;
-};
-
-struct IrInstructionCoroResume {
- IrInstruction base;
-
- IrInstruction *awaiter_handle;
-};
-
-struct IrInstructionCoroSave {
- IrInstruction base;
-
- IrInstruction *coro_handle;
-};
-
-struct IrInstructionCoroPromise {
- IrInstruction base;
-
- IrInstruction *coro_handle;
-};
-
-struct IrInstructionCoroAllocHelper {
- IrInstruction base;
-
- IrInstruction *realloc_fn;
- IrInstruction *coro_size;
-};
-
struct IrInstructionAtomicRmw {
IrInstruction base;
@@ -3518,18 +3358,6 @@ struct IrInstructionAtomicLoad {
AtomicOrder resolved_ordering;
};
-struct IrInstructionPromiseResultType {
- IrInstruction base;
-
- IrInstruction *promise_type;
-};
-
-struct IrInstructionAwaitBookkeeping {
- IrInstruction base;
-
- IrInstruction *promise_result_type;
-};
-
struct IrInstructionSaveErrRetAddr {
IrInstruction base;
};
@@ -3540,14 +3368,6 @@ struct IrInstructionAddImplicitReturnType {
IrInstruction *value;
};
-struct IrInstructionMergeErrRetTraces {
- IrInstruction base;
-
- IrInstruction *coro_promise_ptr;
- IrInstruction *src_err_ret_trace_ptr;
- IrInstruction *dest_err_ret_trace_ptr;
-};
-
struct IrInstructionMarkErrRetTracePtr {
IrInstruction base;
@@ -3777,17 +3597,6 @@ static const size_t err_union_payload_index = 1;
// MUST BE A POWER OF TWO.
static const size_t stack_trace_ptr_count = 32;
-// these belong to the async function
-#define RETURN_ADDRESSES_FIELD_NAME "return_addresses"
-#define ERR_RET_TRACE_FIELD_NAME "err_ret_trace"
-#define RESULT_FIELD_NAME "result"
-#define ASYNC_REALLOC_FIELD_NAME "reallocFn"
-#define ASYNC_SHRINK_FIELD_NAME "shrinkFn"
-#define ATOMIC_STATE_FIELD_NAME "atomic_state"
-// these point to data belonging to the awaiter
-#define ERR_RET_TRACE_PTR_FIELD_NAME "err_ret_trace_ptr"
-#define RESULT_PTR_FIELD_NAME "result_ptr"
-
#define NAMESPACE_SEP_CHAR '.'
#define NAMESPACE_SEP_STR "."
diff --git a/src/analyze.cpp b/src/analyze.cpp
index de4d64f5d6..15e12caa8d 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -188,12 +188,6 @@ Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent) {
return &scope->base;
}
-Scope *create_coro_prelude_scope(CodeGen *g, AstNode *node, Scope *parent) {
- ScopeCoroPrelude *scope = allocate(1);
- init_scope(g, &scope->base, ScopeIdCoroPrelude, node, parent);
- return &scope->base;
-}
-
ZigType *get_scope_import(Scope *scope) {
while (scope) {
if (scope->id == ScopeIdDecls) {
@@ -254,7 +248,6 @@ AstNode *type_decl_node(ZigType *type_entry) {
case ZigTypeIdFn:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
- case ZigTypeIdPromise:
case ZigTypeIdVector:
return nullptr;
}
@@ -307,7 +300,6 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) {
case ZigTypeIdFn:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
- case ZigTypeIdPromise:
case ZigTypeIdVector:
return true;
}
@@ -341,31 +333,6 @@ ZigType *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) {
return get_int_type(g, false, bits_needed_for_unsigned(x));
}
-ZigType *get_promise_type(CodeGen *g, ZigType *result_type) {
- if (result_type != nullptr && result_type->promise_parent != nullptr) {
- return result_type->promise_parent;
- } else if (result_type == nullptr && g->builtin_types.entry_promise != nullptr) {
- return g->builtin_types.entry_promise;
- }
-
- ZigType *entry = new_type_table_entry(ZigTypeIdPromise);
- entry->abi_size = g->builtin_types.entry_usize->abi_size;
- entry->size_in_bits = g->builtin_types.entry_usize->size_in_bits;
- entry->abi_align = g->builtin_types.entry_usize->abi_align;
- entry->data.promise.result_type = result_type;
- buf_init_from_str(&entry->name, "promise");
- if (result_type != nullptr) {
- buf_appendf(&entry->name, "->%s", buf_ptr(&result_type->name));
- }
-
- if (result_type != nullptr) {
- result_type->promise_parent = entry;
- } else if (result_type == nullptr) {
- g->builtin_types.entry_promise = entry;
- }
- return entry;
-}
-
static const char *ptr_len_to_star_str(PtrLen ptr_len) {
switch (ptr_len) {
case PtrLenSingle:
@@ -490,42 +457,6 @@ ZigType *get_pointer_to_type(CodeGen *g, ZigType *child_type, bool is_const) {
return get_pointer_to_type_extra(g, child_type, is_const, false, PtrLenSingle, 0, 0, 0, false);
}
-ZigType *get_promise_frame_type(CodeGen *g, ZigType *return_type) {
- if (return_type->promise_frame_parent != nullptr) {
- return return_type->promise_frame_parent;
- }
-
- ZigType *atomic_state_type = g->builtin_types.entry_usize;
- ZigType *result_ptr_type = get_pointer_to_type(g, return_type, false);
-
- ZigList field_names = {};
- field_names.append(ATOMIC_STATE_FIELD_NAME);
- field_names.append(RESULT_FIELD_NAME);
- field_names.append(RESULT_PTR_FIELD_NAME);
- if (g->have_err_ret_tracing) {
- field_names.append(ERR_RET_TRACE_PTR_FIELD_NAME);
- field_names.append(ERR_RET_TRACE_FIELD_NAME);
- field_names.append(RETURN_ADDRESSES_FIELD_NAME);
- }
-
- ZigList field_types = {};
- field_types.append(atomic_state_type);
- field_types.append(return_type);
- field_types.append(result_ptr_type);
- if (g->have_err_ret_tracing) {
- field_types.append(get_ptr_to_stack_trace_type(g));
- field_types.append(g->stack_trace_type);
- field_types.append(get_array_type(g, g->builtin_types.entry_usize, stack_trace_ptr_count));
- }
-
- assert(field_names.length == field_types.length);
- Buf *name = buf_sprintf("AsyncFramePromise(%s)", buf_ptr(&return_type->name));
- ZigType *entry = get_struct_type(g, buf_ptr(name), field_names.items, field_types.items, field_names.length);
-
- return_type->promise_frame_parent = entry;
- return entry;
-}
-
ZigType *get_optional_type(CodeGen *g, ZigType *child_type) {
if (child_type->optional_parent != nullptr) {
return child_type->optional_parent;
@@ -879,13 +810,8 @@ ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
// populate the name of the type
buf_resize(&fn_type->name, 0);
- if (fn_type->data.fn.fn_type_id.cc == CallingConventionAsync) {
- assert(fn_type_id->async_allocator_type != nullptr);
- buf_appendf(&fn_type->name, "async<%s> ", buf_ptr(&fn_type_id->async_allocator_type->name));
- } else {
- const char *cc_str = calling_convention_fn_type_str(fn_type->data.fn.fn_type_id.cc);
- buf_appendf(&fn_type->name, "%s", cc_str);
- }
+ const char *cc_str = calling_convention_fn_type_str(fn_type->data.fn.fn_type_id.cc);
+ buf_appendf(&fn_type->name, "%s", cc_str);
buf_appendf(&fn_type->name, "fn(");
for (size_t i = 0; i < fn_type_id->param_count; i += 1) {
FnTypeParamInfo *param_info = &fn_type_id->param_info[i];
@@ -998,14 +924,8 @@ ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) {
ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
ZigType *fn_type = new_type_table_entry(ZigTypeIdFn);
buf_resize(&fn_type->name, 0);
- if (fn_type->data.fn.fn_type_id.cc == CallingConventionAsync) {
- const char *async_allocator_type_str = (fn_type->data.fn.fn_type_id.async_allocator_type == nullptr) ?
- "var" : buf_ptr(&fn_type_id->async_allocator_type->name);
- buf_appendf(&fn_type->name, "async(%s) ", async_allocator_type_str);
- } else {
- const char *cc_str = calling_convention_fn_type_str(fn_type->data.fn.fn_type_id.cc);
- buf_appendf(&fn_type->name, "%s", cc_str);
- }
+ const char *cc_str = calling_convention_fn_type_str(fn_type->data.fn.fn_type_id.cc);
+ buf_appendf(&fn_type->name, "%s", cc_str);
buf_appendf(&fn_type->name, "fn(");
size_t i = 0;
for (; i < fn_type_id->next_param_index; i += 1) {
@@ -1119,7 +1039,6 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdOpaque:
- case ZigTypeIdPromise:
add_node_error(g, source_node,
buf_sprintf("type '%s' not allowed in packed struct; no guaranteed in-memory representation",
buf_ptr(&type_entry->name)));
@@ -1207,7 +1126,6 @@ bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry) {
case ZigTypeIdErrorSet:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
- case ZigTypeIdPromise:
case ZigTypeIdVoid:
return false;
case ZigTypeIdOpaque:
@@ -1378,7 +1296,6 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
case ZigTypeIdEnum:
case ZigTypeIdUnion:
case ZigTypeIdFn:
- case ZigTypeIdPromise:
case ZigTypeIdVector:
switch (type_requires_comptime(g, type_entry)) {
case ReqCompTimeNo:
@@ -1474,7 +1391,6 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
case ZigTypeIdEnum:
case ZigTypeIdUnion:
case ZigTypeIdFn:
- case ZigTypeIdPromise:
case ZigTypeIdVector:
switch (type_requires_comptime(g, fn_type_id.return_type)) {
case ReqCompTimeInvalid:
@@ -1487,16 +1403,6 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
break;
}
- if (fn_type_id.cc == CallingConventionAsync) {
- if (fn_proto->async_allocator_type == nullptr) {
- return get_generic_fn_type(g, &fn_type_id);
- }
- fn_type_id.async_allocator_type = analyze_type_expr(g, child_scope, fn_proto->async_allocator_type);
- if (type_is_invalid(fn_type_id.async_allocator_type)) {
- return g->builtin_types.entry_invalid;
- }
- }
-
return get_fn_type(g, &fn_type_id);
}
@@ -3039,7 +2945,6 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
case NodeTypeResume:
case NodeTypeAwaitExpr:
case NodeTypeSuspend:
- case NodeTypePromiseType:
case NodeTypeEnumLiteral:
zig_unreachable();
}
@@ -3091,7 +2996,6 @@ ZigType *validate_var_type(CodeGen *g, AstNode *source_node, ZigType *type_entry
case ZigTypeIdUnion:
case ZigTypeIdFn:
case ZigTypeIdBoundFn:
- case ZigTypeIdPromise:
case ZigTypeIdVector:
return type_entry;
}
@@ -3591,7 +3495,6 @@ bool is_container(ZigType *type_entry) {
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdOpaque:
- case ZigTypeIdPromise:
case ZigTypeIdVector:
return false;
}
@@ -3648,7 +3551,6 @@ Error resolve_container_type(CodeGen *g, ZigType *type_entry) {
case ZigTypeIdInvalid:
case ZigTypeIdArgTuple:
case ZigTypeIdOpaque:
- case ZigTypeIdPromise:
case ZigTypeIdVector:
zig_unreachable();
}
@@ -3658,13 +3560,11 @@ Error resolve_container_type(CodeGen *g, ZigType *type_entry) {
ZigType *get_src_ptr_type(ZigType *type) {
if (type->id == ZigTypeIdPointer) return type;
if (type->id == ZigTypeIdFn) return type;
- if (type->id == ZigTypeIdPromise) return type;
if (type->id == ZigTypeIdOptional) {
if (type->data.maybe.child_type->id == ZigTypeIdPointer) {
return type->data.maybe.child_type->data.pointer.allow_zero ? nullptr : type->data.maybe.child_type;
}
if (type->data.maybe.child_type->id == ZigTypeIdFn) return type->data.maybe.child_type;
- if (type->data.maybe.child_type->id == ZigTypeIdPromise) return type->data.maybe.child_type;
}
return nullptr;
}
@@ -3691,8 +3591,6 @@ uint32_t get_ptr_align(CodeGen *g, ZigType *type) {
// when getting the alignment of `?extern fn() void`.
// See http://lists.llvm.org/pipermail/llvm-dev/2018-September/126142.html
return (ptr_type->data.fn.fn_type_id.alignment == 0) ? 1 : ptr_type->data.fn.fn_type_id.alignment;
- } else if (ptr_type->id == ZigTypeIdPromise) {
- return get_coro_frame_align_bytes(g);
} else {
zig_unreachable();
}
@@ -3704,8 +3602,6 @@ bool get_ptr_const(ZigType *type) {
return ptr_type->data.pointer.is_const;
} else if (ptr_type->id == ZigTypeIdFn) {
return true;
- } else if (ptr_type->id == ZigTypeIdPromise) {
- return true;
} else {
zig_unreachable();
}
@@ -4102,7 +3998,6 @@ bool handle_is_ptr(ZigType *type_entry) {
case ZigTypeIdErrorSet:
case ZigTypeIdFn:
case ZigTypeIdEnum:
- case ZigTypeIdPromise:
case ZigTypeIdVector:
return false;
case ZigTypeIdArray:
@@ -4142,7 +4037,6 @@ uint32_t fn_type_id_hash(FnTypeId *id) {
result += ((uint32_t)(id->cc)) * (uint32_t)3349388391;
result += id->is_var_args ? (uint32_t)1931444534 : 0;
result += hash_ptr(id->return_type);
- result += hash_ptr(id->async_allocator_type);
result += id->alignment * 0xd3b3f3e2;
for (size_t i = 0; i < id->param_count; i += 1) {
FnTypeParamInfo *info = &id->param_info[i];
@@ -4157,8 +4051,7 @@ bool fn_type_id_eql(FnTypeId *a, FnTypeId *b) {
a->return_type != b->return_type ||
a->is_var_args != b->is_var_args ||
a->param_count != b->param_count ||
- a->alignment != b->alignment ||
- a->async_allocator_type != b->async_allocator_type)
+ a->alignment != b->alignment)
{
return false;
}
@@ -4320,9 +4213,6 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
return 3677364617 ^ hash_ptr(const_val->data.x_ptr.data.fn.fn_entry);
case ZigTypeIdPointer:
return hash_const_val_ptr(const_val);
- case ZigTypeIdPromise:
- // TODO better hashing algorithm
- return 223048345;
case ZigTypeIdUndefined:
return 162837799;
case ZigTypeIdNull:
@@ -4418,7 +4308,6 @@ static bool can_mutate_comptime_var_state(ConstExprValue *value) {
case ZigTypeIdBoundFn:
case ZigTypeIdFn:
case ZigTypeIdOpaque:
- case ZigTypeIdPromise:
case ZigTypeIdErrorSet:
case ZigTypeIdEnum:
return false;
@@ -4488,7 +4377,6 @@ static bool return_type_is_cacheable(ZigType *return_type) {
case ZigTypeIdBoundFn:
case ZigTypeIdFn:
case ZigTypeIdOpaque:
- case ZigTypeIdPromise:
case ZigTypeIdErrorSet:
case ZigTypeIdEnum:
case ZigTypeIdPointer:
@@ -4623,7 +4511,6 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
case ZigTypeIdFn:
case ZigTypeIdBool:
case ZigTypeIdFloat:
- case ZigTypeIdPromise:
case ZigTypeIdErrorUnion:
return OnePossibleValueNo;
case ZigTypeIdUndefined:
@@ -4712,7 +4599,6 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry) {
case ZigTypeIdFloat:
case ZigTypeIdVoid:
case ZigTypeIdUnreachable:
- case ZigTypeIdPromise:
return ReqCompTimeNo;
}
zig_unreachable();
@@ -5278,7 +5164,6 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {
case ZigTypeIdBoundFn:
case ZigTypeIdInvalid:
case ZigTypeIdUnreachable:
- case ZigTypeIdPromise:
zig_unreachable();
}
zig_unreachable();
@@ -5611,8 +5496,6 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
buf_appendf(buf, "(args value)");
return;
}
- case ZigTypeIdPromise:
- zig_unreachable();
}
zig_unreachable();
}
@@ -5659,7 +5542,6 @@ uint32_t type_id_hash(TypeId x) {
case ZigTypeIdFn:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
- case ZigTypeIdPromise:
zig_unreachable();
case ZigTypeIdErrorUnion:
return hash_ptr(x.data.error_union.err_set_type) ^ hash_ptr(x.data.error_union.payload_type);
@@ -5701,7 +5583,6 @@ bool type_id_eql(TypeId a, TypeId b) {
case ZigTypeIdUndefined:
case ZigTypeIdNull:
case ZigTypeIdOptional:
- case ZigTypeIdPromise:
case ZigTypeIdErrorSet:
case ZigTypeIdEnum:
case ZigTypeIdUnion:
@@ -5874,7 +5755,6 @@ static const ZigTypeId all_type_ids[] = {
ZigTypeIdBoundFn,
ZigTypeIdArgTuple,
ZigTypeIdOpaque,
- ZigTypeIdPromise,
ZigTypeIdVector,
ZigTypeIdEnumLiteral,
};
@@ -5938,12 +5818,10 @@ size_t type_id_index(ZigType *entry) {
return 20;
case ZigTypeIdOpaque:
return 21;
- case ZigTypeIdPromise:
- return 22;
case ZigTypeIdVector:
- return 23;
+ return 22;
case ZigTypeIdEnumLiteral:
- return 24;
+ return 23;
}
zig_unreachable();
}
@@ -5998,8 +5876,6 @@ const char *type_id_name(ZigTypeId id) {
return "ArgTuple";
case ZigTypeIdOpaque:
return "Opaque";
- case ZigTypeIdPromise:
- return "Promise";
case ZigTypeIdVector:
return "Vector";
}
@@ -6066,13 +5942,6 @@ bool type_is_global_error_set(ZigType *err_set_type) {
return err_set_type->data.error_set.err_count == UINT32_MAX;
}
-uint32_t get_coro_frame_align_bytes(CodeGen *g) {
- uint32_t a = g->pointer_size_bytes * 2;
- // promises have at least alignment 8 so that we can have 3 extra bits when doing atomicrmw
- if (a < 8) a = 8;
- return a;
-}
-
bool type_can_fail(ZigType *type_entry) {
return type_entry->id == ZigTypeIdErrorUnion || type_entry->id == ZigTypeIdErrorSet;
}
@@ -7105,19 +6974,13 @@ static void resolve_llvm_types_fn(CodeGen *g, ZigType *fn_type) {
param_di_types.append(get_llvm_di_type(g, gen_type));
}
if (is_async) {
- {
- // async allocator param
- ZigType *gen_type = fn_type_id->async_allocator_type;
- gen_param_types.append(get_llvm_type(g, gen_type));
- param_di_types.append(get_llvm_di_type(g, gen_type));
- }
-
- {
- // error code pointer
- ZigType *gen_type = get_pointer_to_type(g, g->builtin_types.entry_global_error_set, false);
- gen_param_types.append(get_llvm_type(g, gen_type));
- param_di_types.append(get_llvm_di_type(g, gen_type));
- }
+ // coroutine frame pointer
+ // TODO if we can make this typed a little more it will be better for
+ // debug symbols.
+ // TODO do we need to make this aligned more?
+ ZigType *void_star = get_pointer_to_type(g, g->builtin_types.entry_c_void, false);
+ gen_param_types.append(get_llvm_type(g, void_star));
+ param_di_types.append(get_llvm_di_type(g, void_star));
}
fn_type->data.fn.gen_param_info = allocate(fn_type_id->param_count);
@@ -7224,13 +7087,6 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_r
return resolve_llvm_types_union(g, type, wanted_resolve_status);
case ZigTypeIdPointer:
return resolve_llvm_types_pointer(g, type);
- case ZigTypeIdPromise: {
- if (type->llvm_di_type != nullptr) return;
- ZigType *u8_ptr_type = get_pointer_to_type(g, g->builtin_types.entry_u8, false);
- type->llvm_type = get_llvm_type(g, u8_ptr_type);
- type->llvm_di_type = get_llvm_di_type(g, u8_ptr_type);
- return;
- }
case ZigTypeIdInt:
return resolve_llvm_types_integer(g, type);
case ZigTypeIdOptional:
diff --git a/src/analyze.hpp b/src/analyze.hpp
index b9e9f2df7d..fbbdece8ba 100644
--- a/src/analyze.hpp
+++ b/src/analyze.hpp
@@ -39,8 +39,6 @@ ZigType *get_bound_fn_type(CodeGen *g, ZigFn *fn_entry);
ZigType *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *full_name, Buf *bare_name);
ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[],
ZigType *field_types[], size_t field_count);
-ZigType *get_promise_type(CodeGen *g, ZigType *result_type);
-ZigType *get_promise_frame_type(CodeGen *g, ZigType *return_type);
ZigType *get_test_fn_type(CodeGen *g);
bool handle_is_ptr(ZigType *type_entry);
@@ -117,7 +115,6 @@ ScopeLoop *create_loop_scope(CodeGen *g, AstNode *node, Scope *parent);
ScopeSuspend *create_suspend_scope(CodeGen *g, AstNode *node, Scope *parent);
ScopeFnDef *create_fndef_scope(CodeGen *g, AstNode *node, Scope *parent, ZigFn *fn_entry);
Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent);
-Scope *create_coro_prelude_scope(CodeGen *g, AstNode *node, Scope *parent);
Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstruction *is_comptime);
void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str);
@@ -204,7 +201,6 @@ bool resolve_inferred_error_set(CodeGen *g, ZigType *err_set_type, AstNode *sour
ZigType *get_auto_err_set_type(CodeGen *g, ZigFn *fn_entry);
-uint32_t get_coro_frame_align_bytes(CodeGen *g);
bool fn_type_can_fail(FnTypeId *fn_type_id);
bool type_can_fail(ZigType *type_entry);
bool fn_eval_cacheable(Scope *scope, ZigType *return_type);
diff --git a/src/ast_render.cpp b/src/ast_render.cpp
index fe131ab65f..d97f58fdec 100644
--- a/src/ast_render.cpp
+++ b/src/ast_render.cpp
@@ -257,8 +257,6 @@ static const char *node_type_str(NodeType node_type) {
return "AwaitExpr";
case NodeTypeSuspend:
return "Suspend";
- case NodeTypePromiseType:
- return "PromiseType";
case NodeTypePointerType:
return "PointerType";
case NodeTypeEnumLiteral:
@@ -692,13 +690,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
fprintf(ar->f, "@");
}
if (node->data.fn_call_expr.is_async) {
- fprintf(ar->f, "async");
- if (node->data.fn_call_expr.async_allocator != nullptr) {
- fprintf(ar->f, "<");
- render_node_extra(ar, node->data.fn_call_expr.async_allocator, true);
- fprintf(ar->f, ">");
- }
- fprintf(ar->f, " ");
+ fprintf(ar->f, "async ");
}
AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;
bool grouped = (fn_ref_node->type != NodeTypePrefixOpExpr && fn_ref_node->type != NodeTypePointerType);
@@ -855,15 +847,6 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
render_node_ungrouped(ar, node->data.inferred_array_type.child_type);
break;
}
- case NodeTypePromiseType:
- {
- fprintf(ar->f, "promise");
- if (node->data.promise_type.payload_type != nullptr) {
- fprintf(ar->f, "->");
- render_node_grouped(ar, node->data.promise_type.payload_type);
- }
- break;
- }
case NodeTypeErrorType:
fprintf(ar->f, "anyerror");
break;
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 188c5ccc8d..4cc99b39a8 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -721,7 +721,6 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
case ScopeIdLoop:
case ScopeIdSuspend:
case ScopeIdCompTime:
- case ScopeIdCoroPrelude:
case ScopeIdRuntime:
return get_di_scope(g, scope->parent);
}
@@ -1083,177 +1082,6 @@ static LLVMValueRef get_write_register_fn_val(CodeGen *g) {
return g->write_register_fn_val;
}
-static LLVMValueRef get_coro_destroy_fn_val(CodeGen *g) {
- if (g->coro_destroy_fn_val)
- return g->coro_destroy_fn_val;
-
- LLVMTypeRef param_types[] = {
- LLVMPointerType(LLVMInt8Type(), 0),
- };
- LLVMTypeRef fn_type = LLVMFunctionType(LLVMVoidType(), param_types, 1, false);
- Buf *name = buf_sprintf("llvm.coro.destroy");
- g->coro_destroy_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
- assert(LLVMGetIntrinsicID(g->coro_destroy_fn_val));
-
- return g->coro_destroy_fn_val;
-}
-
-static LLVMValueRef get_coro_id_fn_val(CodeGen *g) {
- if (g->coro_id_fn_val)
- return g->coro_id_fn_val;
-
- LLVMTypeRef param_types[] = {
- LLVMInt32Type(),
- LLVMPointerType(LLVMInt8Type(), 0),
- LLVMPointerType(LLVMInt8Type(), 0),
- LLVMPointerType(LLVMInt8Type(), 0),
- };
- LLVMTypeRef fn_type = LLVMFunctionType(ZigLLVMTokenTypeInContext(LLVMGetGlobalContext()), param_types, 4, false);
- Buf *name = buf_sprintf("llvm.coro.id");
- g->coro_id_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
- assert(LLVMGetIntrinsicID(g->coro_id_fn_val));
-
- return g->coro_id_fn_val;
-}
-
-static LLVMValueRef get_coro_alloc_fn_val(CodeGen *g) {
- if (g->coro_alloc_fn_val)
- return g->coro_alloc_fn_val;
-
- LLVMTypeRef param_types[] = {
- ZigLLVMTokenTypeInContext(LLVMGetGlobalContext()),
- };
- LLVMTypeRef fn_type = LLVMFunctionType(LLVMInt1Type(), param_types, 1, false);
- Buf *name = buf_sprintf("llvm.coro.alloc");
- g->coro_alloc_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
- assert(LLVMGetIntrinsicID(g->coro_alloc_fn_val));
-
- return g->coro_alloc_fn_val;
-}
-
-static LLVMValueRef get_coro_size_fn_val(CodeGen *g) {
- if (g->coro_size_fn_val)
- return g->coro_size_fn_val;
-
- LLVMTypeRef fn_type = LLVMFunctionType(g->builtin_types.entry_usize->llvm_type, nullptr, 0, false);
- Buf *name = buf_sprintf("llvm.coro.size.i%d", g->pointer_size_bytes * 8);
- g->coro_size_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
- assert(LLVMGetIntrinsicID(g->coro_size_fn_val));
-
- return g->coro_size_fn_val;
-}
-
-static LLVMValueRef get_coro_begin_fn_val(CodeGen *g) {
- if (g->coro_begin_fn_val)
- return g->coro_begin_fn_val;
-
- LLVMTypeRef param_types[] = {
- ZigLLVMTokenTypeInContext(LLVMGetGlobalContext()),
- LLVMPointerType(LLVMInt8Type(), 0),
- };
- LLVMTypeRef fn_type = LLVMFunctionType(LLVMPointerType(LLVMInt8Type(), 0), param_types, 2, false);
- Buf *name = buf_sprintf("llvm.coro.begin");
- g->coro_begin_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
- assert(LLVMGetIntrinsicID(g->coro_begin_fn_val));
-
- return g->coro_begin_fn_val;
-}
-
-static LLVMValueRef get_coro_suspend_fn_val(CodeGen *g) {
- if (g->coro_suspend_fn_val)
- return g->coro_suspend_fn_val;
-
- LLVMTypeRef param_types[] = {
- ZigLLVMTokenTypeInContext(LLVMGetGlobalContext()),
- LLVMInt1Type(),
- };
- LLVMTypeRef fn_type = LLVMFunctionType(LLVMInt8Type(), param_types, 2, false);
- Buf *name = buf_sprintf("llvm.coro.suspend");
- g->coro_suspend_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
- assert(LLVMGetIntrinsicID(g->coro_suspend_fn_val));
-
- return g->coro_suspend_fn_val;
-}
-
-static LLVMValueRef get_coro_end_fn_val(CodeGen *g) {
- if (g->coro_end_fn_val)
- return g->coro_end_fn_val;
-
- LLVMTypeRef param_types[] = {
- LLVMPointerType(LLVMInt8Type(), 0),
- LLVMInt1Type(),
- };
- LLVMTypeRef fn_type = LLVMFunctionType(LLVMInt1Type(), param_types, 2, false);
- Buf *name = buf_sprintf("llvm.coro.end");
- g->coro_end_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
- assert(LLVMGetIntrinsicID(g->coro_end_fn_val));
-
- return g->coro_end_fn_val;
-}
-
-static LLVMValueRef get_coro_free_fn_val(CodeGen *g) {
- if (g->coro_free_fn_val)
- return g->coro_free_fn_val;
-
- LLVMTypeRef param_types[] = {
- ZigLLVMTokenTypeInContext(LLVMGetGlobalContext()),
- LLVMPointerType(LLVMInt8Type(), 0),
- };
- LLVMTypeRef fn_type = LLVMFunctionType(LLVMPointerType(LLVMInt8Type(), 0), param_types, 2, false);
- Buf *name = buf_sprintf("llvm.coro.free");
- g->coro_free_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
- assert(LLVMGetIntrinsicID(g->coro_free_fn_val));
-
- return g->coro_free_fn_val;
-}
-
-static LLVMValueRef get_coro_resume_fn_val(CodeGen *g) {
- if (g->coro_resume_fn_val)
- return g->coro_resume_fn_val;
-
- LLVMTypeRef param_types[] = {
- LLVMPointerType(LLVMInt8Type(), 0),
- };
- LLVMTypeRef fn_type = LLVMFunctionType(LLVMVoidType(), param_types, 1, false);
- Buf *name = buf_sprintf("llvm.coro.resume");
- g->coro_resume_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
- assert(LLVMGetIntrinsicID(g->coro_resume_fn_val));
-
- return g->coro_resume_fn_val;
-}
-
-static LLVMValueRef get_coro_save_fn_val(CodeGen *g) {
- if (g->coro_save_fn_val)
- return g->coro_save_fn_val;
-
- LLVMTypeRef param_types[] = {
- LLVMPointerType(LLVMInt8Type(), 0),
- };
- LLVMTypeRef fn_type = LLVMFunctionType(ZigLLVMTokenTypeInContext(LLVMGetGlobalContext()), param_types, 1, false);
- Buf *name = buf_sprintf("llvm.coro.save");
- g->coro_save_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
- assert(LLVMGetIntrinsicID(g->coro_save_fn_val));
-
- return g->coro_save_fn_val;
-}
-
-static LLVMValueRef get_coro_promise_fn_val(CodeGen *g) {
- if (g->coro_promise_fn_val)
- return g->coro_promise_fn_val;
-
- LLVMTypeRef param_types[] = {
- LLVMPointerType(LLVMInt8Type(), 0),
- LLVMInt32Type(),
- LLVMInt1Type(),
- };
- LLVMTypeRef fn_type = LLVMFunctionType(LLVMPointerType(LLVMInt8Type(), 0), param_types, 3, false);
- Buf *name = buf_sprintf("llvm.coro.promise");
- g->coro_promise_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
- assert(LLVMGetIntrinsicID(g->coro_promise_fn_val));
-
- return g->coro_promise_fn_val;
-}
-
static LLVMValueRef get_return_address_fn_val(CodeGen *g) {
if (g->return_address_fn_val)
return g->return_address_fn_val;
@@ -1346,140 +1174,6 @@ static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) {
return fn_val;
}
-static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
- if (g->merge_err_ret_traces_fn_val)
- return g->merge_err_ret_traces_fn_val;
-
- assert(g->stack_trace_type != nullptr);
-
- LLVMTypeRef param_types[] = {
- get_llvm_type(g, get_ptr_to_stack_trace_type(g)),
- get_llvm_type(g, get_ptr_to_stack_trace_type(g)),
- };
- LLVMTypeRef fn_type_ref = LLVMFunctionType(LLVMVoidType(), param_types, 2, false);
-
- Buf *fn_name = get_mangled_name(g, buf_create_from_str("__zig_merge_error_return_traces"), false);
- LLVMValueRef fn_val = LLVMAddFunction(g->module, buf_ptr(fn_name), fn_type_ref);
- LLVMSetLinkage(fn_val, LLVMInternalLinkage);
- LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));
- addLLVMFnAttr(fn_val, "nounwind");
- add_uwtable_attr(g, fn_val);
- // Error return trace memory is in the stack, which is impossible to be at address 0
- // on any architecture.
- addLLVMArgAttr(fn_val, (unsigned)0, "nonnull");
- addLLVMArgAttr(fn_val, (unsigned)0, "noalias");
- addLLVMArgAttr(fn_val, (unsigned)0, "writeonly");
- // Error return trace memory is in the stack, which is impossible to be at address 0
- // on any architecture.
- addLLVMArgAttr(fn_val, (unsigned)1, "nonnull");
- addLLVMArgAttr(fn_val, (unsigned)1, "noalias");
- addLLVMArgAttr(fn_val, (unsigned)1, "readonly");
- if (g->build_mode == BuildModeDebug) {
- ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim", "true");
- ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim-non-leaf", nullptr);
- }
-
- // this is above the ZigLLVMClearCurrentDebugLocation
- LLVMValueRef add_error_return_trace_addr_fn_val = get_add_error_return_trace_addr_fn(g);
-
- LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn_val, "Entry");
- LLVMBasicBlockRef prev_block = LLVMGetInsertBlock(g->builder);
- LLVMValueRef prev_debug_location = LLVMGetCurrentDebugLocation(g->builder);
- LLVMPositionBuilderAtEnd(g->builder, entry_block);
- ZigLLVMClearCurrentDebugLocation(g->builder);
-
- // var frame_index: usize = undefined;
- // var frames_left: usize = undefined;
- // if (src_stack_trace.index < src_stack_trace.instruction_addresses.len) {
- // frame_index = 0;
- // frames_left = src_stack_trace.index;
- // if (frames_left == 0) return;
- // } else {
- // frame_index = (src_stack_trace.index + 1) % src_stack_trace.instruction_addresses.len;
- // frames_left = src_stack_trace.instruction_addresses.len;
- // }
- // while (true) {
- // __zig_add_err_ret_trace_addr(dest_stack_trace, src_stack_trace.instruction_addresses[frame_index]);
- // frames_left -= 1;
- // if (frames_left == 0) return;
- // frame_index = (frame_index + 1) % src_stack_trace.instruction_addresses.len;
- // }
- LLVMBasicBlockRef return_block = LLVMAppendBasicBlock(fn_val, "Return");
-
- LLVMValueRef frame_index_ptr = LLVMBuildAlloca(g->builder, g->builtin_types.entry_usize->llvm_type, "frame_index");
- LLVMValueRef frames_left_ptr = LLVMBuildAlloca(g->builder, g->builtin_types.entry_usize->llvm_type, "frames_left");
-
- LLVMValueRef dest_stack_trace_ptr = LLVMGetParam(fn_val, 0);
- LLVMValueRef src_stack_trace_ptr = LLVMGetParam(fn_val, 1);
-
- size_t src_index_field_index = g->stack_trace_type->data.structure.fields[0].gen_index;
- size_t src_addresses_field_index = g->stack_trace_type->data.structure.fields[1].gen_index;
- LLVMValueRef src_index_field_ptr = LLVMBuildStructGEP(g->builder, src_stack_trace_ptr,
- (unsigned)src_index_field_index, "");
- LLVMValueRef src_addresses_field_ptr = LLVMBuildStructGEP(g->builder, src_stack_trace_ptr,
- (unsigned)src_addresses_field_index, "");
- ZigType *slice_type = g->stack_trace_type->data.structure.fields[1].type_entry;
- size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index].gen_index;
- LLVMValueRef src_ptr_field_ptr = LLVMBuildStructGEP(g->builder, src_addresses_field_ptr, (unsigned)ptr_field_index, "");
- size_t len_field_index = slice_type->data.structure.fields[slice_len_index].gen_index;
- LLVMValueRef src_len_field_ptr = LLVMBuildStructGEP(g->builder, src_addresses_field_ptr, (unsigned)len_field_index, "");
- LLVMValueRef src_index_val = LLVMBuildLoad(g->builder, src_index_field_ptr, "");
- LLVMValueRef src_ptr_val = LLVMBuildLoad(g->builder, src_ptr_field_ptr, "");
- LLVMValueRef src_len_val = LLVMBuildLoad(g->builder, src_len_field_ptr, "");
- LLVMValueRef no_wrap_bit = LLVMBuildICmp(g->builder, LLVMIntULT, src_index_val, src_len_val, "");
- LLVMBasicBlockRef no_wrap_block = LLVMAppendBasicBlock(fn_val, "NoWrap");
- LLVMBasicBlockRef yes_wrap_block = LLVMAppendBasicBlock(fn_val, "YesWrap");
- LLVMBasicBlockRef loop_block = LLVMAppendBasicBlock(fn_val, "Loop");
- LLVMBuildCondBr(g->builder, no_wrap_bit, no_wrap_block, yes_wrap_block);
-
- LLVMPositionBuilderAtEnd(g->builder, no_wrap_block);
- LLVMValueRef usize_zero = LLVMConstNull(g->builtin_types.entry_usize->llvm_type);
- LLVMBuildStore(g->builder, usize_zero, frame_index_ptr);
- LLVMBuildStore(g->builder, src_index_val, frames_left_ptr);
- LLVMValueRef frames_left_eq_zero_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, src_index_val, usize_zero, "");
- LLVMBuildCondBr(g->builder, frames_left_eq_zero_bit, return_block, loop_block);
-
- LLVMPositionBuilderAtEnd(g->builder, yes_wrap_block);
- LLVMValueRef usize_one = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, 1, false);
- LLVMValueRef plus_one = LLVMBuildNUWAdd(g->builder, src_index_val, usize_one, "");
- LLVMValueRef mod_len = LLVMBuildURem(g->builder, plus_one, src_len_val, "");
- LLVMBuildStore(g->builder, mod_len, frame_index_ptr);
- LLVMBuildStore(g->builder, src_len_val, frames_left_ptr);
- LLVMBuildBr(g->builder, loop_block);
-
- LLVMPositionBuilderAtEnd(g->builder, loop_block);
- LLVMValueRef ptr_index = LLVMBuildLoad(g->builder, frame_index_ptr, "");
- LLVMValueRef addr_ptr = LLVMBuildInBoundsGEP(g->builder, src_ptr_val, &ptr_index, 1, "");
- LLVMValueRef this_addr_val = LLVMBuildLoad(g->builder, addr_ptr, "");
- LLVMValueRef args[] = {dest_stack_trace_ptr, this_addr_val};
- ZigLLVMBuildCall(g->builder, add_error_return_trace_addr_fn_val, args, 2, get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_FnInlineAlways, "");
- LLVMValueRef prev_frames_left = LLVMBuildLoad(g->builder, frames_left_ptr, "");
- LLVMValueRef new_frames_left = LLVMBuildNUWSub(g->builder, prev_frames_left, usize_one, "");
- LLVMValueRef done_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, new_frames_left, usize_zero, "");
- LLVMBasicBlockRef continue_block = LLVMAppendBasicBlock(fn_val, "Continue");
- LLVMBuildCondBr(g->builder, done_bit, return_block, continue_block);
-
- LLVMPositionBuilderAtEnd(g->builder, return_block);
- LLVMBuildRetVoid(g->builder);
-
- LLVMPositionBuilderAtEnd(g->builder, continue_block);
- LLVMBuildStore(g->builder, new_frames_left, frames_left_ptr);
- LLVMValueRef prev_index = LLVMBuildLoad(g->builder, frame_index_ptr, "");
- LLVMValueRef index_plus_one = LLVMBuildNUWAdd(g->builder, prev_index, usize_one, "");
- LLVMValueRef index_mod_len = LLVMBuildURem(g->builder, index_plus_one, src_len_val, "");
- LLVMBuildStore(g->builder, index_mod_len, frame_index_ptr);
- LLVMBuildBr(g->builder, loop_block);
-
- LLVMPositionBuilderAtEnd(g->builder, prev_block);
- if (!g->strip_debug_symbols) {
- LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
- }
-
- g->merge_err_ret_traces_fn_val = fn_val;
- return fn_val;
-
-}
-
static LLVMValueRef get_return_err_fn(CodeGen *g) {
if (g->return_err_fn != nullptr)
return g->return_err_fn;
@@ -1667,24 +1361,12 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
return fn_val;
}
-static bool is_coro_prelude_scope(Scope *scope) {
- while (scope != nullptr) {
- if (scope->id == ScopeIdCoroPrelude) {
- return true;
- } else if (scope->id == ScopeIdFnDef) {
- break;
- }
- scope = scope->parent;
- }
- return false;
-}
-
static LLVMValueRef get_cur_err_ret_trace_val(CodeGen *g, Scope *scope) {
if (!g->have_err_ret_tracing) {
return nullptr;
}
if (g->cur_fn->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync) {
- return is_coro_prelude_scope(scope) ? g->cur_err_ret_trace_val_arg : g->cur_err_ret_trace_val_stack;
+ return g->cur_err_ret_trace_val_stack;
}
if (g->cur_err_ret_trace_val_stack != nullptr) {
return g->cur_err_ret_trace_val_stack;
@@ -3697,19 +3379,6 @@ static bool get_prefix_arg_err_ret_stack(CodeGen *g, FnTypeId *fn_type_id) {
fn_type_id->cc == CallingConventionAsync);
}
-static size_t get_async_allocator_arg_index(CodeGen *g, FnTypeId *fn_type_id) {
- // 0 1 2 3
- // err_ret_stack allocator_ptr err_code other_args...
- return get_prefix_arg_err_ret_stack(g, fn_type_id) ? 1 : 0;
-}
-
-static size_t get_async_err_code_arg_index(CodeGen *g, FnTypeId *fn_type_id) {
- // 0 1 2 3
- // err_ret_stack allocator_ptr err_code other_args...
- return 1 + get_async_allocator_arg_index(g, fn_type_id);
-}
-
-
static LLVMValueRef get_new_stack_addr(CodeGen *g, LLVMValueRef new_stack) {
LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, new_stack, (unsigned)slice_ptr_index, "");
LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, new_stack, (unsigned)slice_len_index, "");
@@ -3778,10 +3447,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
gen_param_values.append(get_cur_err_ret_trace_val(g, instruction->base.scope));
}
if (instruction->is_async) {
- gen_param_values.append(ir_llvm_value(g, instruction->async_allocator));
-
- LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_err_index, "");
- gen_param_values.append(err_val_ptr);
+ zig_panic("TODO codegen async call");
}
FnWalk fn_walk = {};
fn_walk.id = FnWalkIdCall;
@@ -4471,10 +4137,6 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, IrExecutable *executable, I
{
align_bytes = target_type->data.maybe.child_type->data.fn.fn_type_id.alignment;
ptr_val = target_val;
- } else if (target_type->id == ZigTypeIdOptional &&
- target_type->data.maybe.child_type->id == ZigTypeIdPromise)
- {
- zig_panic("TODO audit this function");
} else if (target_type->id == ZigTypeIdStruct && target_type->data.structure.is_slice) {
ZigType *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index].type_entry;
align_bytes = get_ptr_align(g, slice_ptr_type);
@@ -4519,17 +4181,7 @@ static LLVMValueRef ir_render_error_return_trace(CodeGen *g, IrExecutable *execu
}
static LLVMValueRef ir_render_cancel(CodeGen *g, IrExecutable *executable, IrInstructionCancel *instruction) {
- LLVMValueRef target_handle = ir_llvm_value(g, instruction->target);
- LLVMBuildCall(g->builder, get_coro_destroy_fn_val(g), &target_handle, 1, "");
- return nullptr;
-}
-
-static LLVMValueRef ir_render_get_implicit_allocator(CodeGen *g, IrExecutable *executable,
- IrInstructionGetImplicitAllocator *instruction)
-{
- assert(instruction->id == ImplicitAllocatorIdArg);
- size_t allocator_arg_index = get_async_allocator_arg_index(g, &g->cur_fn->type_entry->data.fn.fn_type_id);
- return LLVMGetParam(g->cur_fn_val, allocator_arg_index);
+ zig_panic("TODO cancel");
}
static LLVMAtomicOrdering to_LLVMAtomicOrdering(AtomicOrder atomic_order) {
@@ -4840,24 +4492,10 @@ static LLVMValueRef ir_render_frame_address(CodeGen *g, IrExecutable *executable
return LLVMBuildPtrToInt(g->builder, ptr_val, g->builtin_types.entry_usize->llvm_type, "");
}
-static LLVMValueRef get_handle_fn_val(CodeGen *g) {
- if (g->coro_frame_fn_val)
- return g->coro_frame_fn_val;
-
- LLVMTypeRef fn_type = LLVMFunctionType( LLVMPointerType(LLVMInt8Type(), 0)
- , nullptr, 0, false);
- Buf *name = buf_sprintf("llvm.coro.frame");
- g->coro_frame_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
- assert(LLVMGetIntrinsicID(g->coro_frame_fn_val));
-
- return g->coro_frame_fn_val;
-}
-
static LLVMValueRef ir_render_handle(CodeGen *g, IrExecutable *executable,
IrInstructionHandle *instruction)
{
- LLVMValueRef zero = LLVMConstNull(get_llvm_type(g, g->builtin_types.entry_promise));
- return LLVMBuildCall(g->builder, get_handle_fn_val(g), &zero, 0, "");
+ zig_panic("TODO @handle() codegen");
}
static LLVMValueRef render_shl_with_overflow(CodeGen *g, IrInstructionOverflowOp *instruction) {
@@ -5123,248 +4761,6 @@ static LLVMValueRef ir_render_panic(CodeGen *g, IrExecutable *executable, IrInst
return nullptr;
}
-static LLVMValueRef ir_render_coro_id(CodeGen *g, IrExecutable *executable, IrInstructionCoroId *instruction) {
- LLVMValueRef promise_ptr = ir_llvm_value(g, instruction->promise_ptr);
- LLVMValueRef align_val = LLVMConstInt(LLVMInt32Type(), get_coro_frame_align_bytes(g), false);
- LLVMValueRef null = LLVMConstIntToPtr(LLVMConstNull(g->builtin_types.entry_usize->llvm_type),
- LLVMPointerType(LLVMInt8Type(), 0));
- LLVMValueRef params[] = {
- align_val,
- promise_ptr,
- null,
- null,
- };
- return LLVMBuildCall(g->builder, get_coro_id_fn_val(g), params, 4, "");
-}
-
-static LLVMValueRef ir_render_coro_alloc(CodeGen *g, IrExecutable *executable, IrInstructionCoroAlloc *instruction) {
- LLVMValueRef token = ir_llvm_value(g, instruction->coro_id);
- return LLVMBuildCall(g->builder, get_coro_alloc_fn_val(g), &token, 1, "");
-}
-
-static LLVMValueRef ir_render_coro_size(CodeGen *g, IrExecutable *executable, IrInstructionCoroSize *instruction) {
- return LLVMBuildCall(g->builder, get_coro_size_fn_val(g), nullptr, 0, "");
-}
-
-static LLVMValueRef ir_render_coro_begin(CodeGen *g, IrExecutable *executable, IrInstructionCoroBegin *instruction) {
- LLVMValueRef coro_id = ir_llvm_value(g, instruction->coro_id);
- LLVMValueRef coro_mem_ptr = ir_llvm_value(g, instruction->coro_mem_ptr);
- LLVMValueRef params[] = {
- coro_id,
- coro_mem_ptr,
- };
- return LLVMBuildCall(g->builder, get_coro_begin_fn_val(g), params, 2, "");
-}
-
-static LLVMValueRef ir_render_coro_alloc_fail(CodeGen *g, IrExecutable *executable,
- IrInstructionCoroAllocFail *instruction)
-{
- size_t err_code_ptr_arg_index = get_async_err_code_arg_index(g, &g->cur_fn->type_entry->data.fn.fn_type_id);
- LLVMValueRef err_code_ptr_val = LLVMGetParam(g->cur_fn_val, err_code_ptr_arg_index);
- LLVMValueRef err_code = ir_llvm_value(g, instruction->err_val);
- LLVMBuildStore(g->builder, err_code, err_code_ptr_val);
-
- LLVMValueRef return_value;
- if (ir_want_runtime_safety(g, &instruction->base)) {
- return_value = LLVMConstNull(LLVMPointerType(LLVMInt8Type(), 0));
- } else {
- return_value = LLVMGetUndef(LLVMPointerType(LLVMInt8Type(), 0));
- }
- LLVMBuildRet(g->builder, return_value);
- return nullptr;
-}
-
-static LLVMValueRef ir_render_coro_suspend(CodeGen *g, IrExecutable *executable, IrInstructionCoroSuspend *instruction) {
- LLVMValueRef save_point;
- if (instruction->save_point == nullptr) {
- save_point = LLVMConstNull(ZigLLVMTokenTypeInContext(LLVMGetGlobalContext()));
- } else {
- save_point = ir_llvm_value(g, instruction->save_point);
- }
- LLVMValueRef is_final = ir_llvm_value(g, instruction->is_final);
- LLVMValueRef params[] = {
- save_point,
- is_final,
- };
- return LLVMBuildCall(g->builder, get_coro_suspend_fn_val(g), params, 2, "");
-}
-
-static LLVMValueRef ir_render_coro_end(CodeGen *g, IrExecutable *executable, IrInstructionCoroEnd *instruction) {
- LLVMValueRef params[] = {
- LLVMConstNull(LLVMPointerType(LLVMInt8Type(), 0)),
- LLVMConstNull(LLVMInt1Type()),
- };
- return LLVMBuildCall(g->builder, get_coro_end_fn_val(g), params, 2, "");
-}
-
-static LLVMValueRef ir_render_coro_free(CodeGen *g, IrExecutable *executable, IrInstructionCoroFree *instruction) {
- LLVMValueRef coro_id = ir_llvm_value(g, instruction->coro_id);
- LLVMValueRef coro_handle = ir_llvm_value(g, instruction->coro_handle);
- LLVMValueRef params[] = {
- coro_id,
- coro_handle,
- };
- return LLVMBuildCall(g->builder, get_coro_free_fn_val(g), params, 2, "");
-}
-
-static LLVMValueRef ir_render_coro_resume(CodeGen *g, IrExecutable *executable, IrInstructionCoroResume *instruction) {
- LLVMValueRef awaiter_handle = ir_llvm_value(g, instruction->awaiter_handle);
- return LLVMBuildCall(g->builder, get_coro_resume_fn_val(g), &awaiter_handle, 1, "");
-}
-
-static LLVMValueRef ir_render_coro_save(CodeGen *g, IrExecutable *executable, IrInstructionCoroSave *instruction) {
- LLVMValueRef coro_handle = ir_llvm_value(g, instruction->coro_handle);
- return LLVMBuildCall(g->builder, get_coro_save_fn_val(g), &coro_handle, 1, "");
-}
-
-static LLVMValueRef ir_render_coro_promise(CodeGen *g, IrExecutable *executable, IrInstructionCoroPromise *instruction) {
- LLVMValueRef coro_handle = ir_llvm_value(g, instruction->coro_handle);
- LLVMValueRef params[] = {
- coro_handle,
- LLVMConstInt(LLVMInt32Type(), get_coro_frame_align_bytes(g), false),
- LLVMConstNull(LLVMInt1Type()),
- };
- LLVMValueRef uncasted_result = LLVMBuildCall(g->builder, get_coro_promise_fn_val(g), params, 3, "");
- return LLVMBuildBitCast(g->builder, uncasted_result, get_llvm_type(g, instruction->base.value.type), "");
-}
-
-static LLVMValueRef get_coro_alloc_helper_fn_val(CodeGen *g, LLVMTypeRef alloc_fn_type_ref, ZigType *fn_type) {
- if (g->coro_alloc_helper_fn_val != nullptr)
- return g->coro_alloc_helper_fn_val;
-
- assert(fn_type->id == ZigTypeIdFn);
-
- ZigType *ptr_to_err_code_type = get_pointer_to_type(g, g->builtin_types.entry_global_error_set, false);
-
- LLVMTypeRef alloc_raw_fn_type_ref = LLVMGetElementType(alloc_fn_type_ref);
- LLVMTypeRef *alloc_fn_arg_types = allocate(LLVMCountParamTypes(alloc_raw_fn_type_ref));
- LLVMGetParamTypes(alloc_raw_fn_type_ref, alloc_fn_arg_types);
-
- ZigList arg_types = {};
- arg_types.append(alloc_fn_type_ref);
- if (g->have_err_ret_tracing) {
- arg_types.append(alloc_fn_arg_types[1]);
- }
- arg_types.append(alloc_fn_arg_types[g->have_err_ret_tracing ? 2 : 1]);
- arg_types.append(get_llvm_type(g, ptr_to_err_code_type));
- arg_types.append(g->builtin_types.entry_usize->llvm_type);
-
- LLVMTypeRef fn_type_ref = LLVMFunctionType(LLVMPointerType(LLVMInt8Type(), 0),
- arg_types.items, arg_types.length, false);
-
- Buf *fn_name = get_mangled_name(g, buf_create_from_str("__zig_coro_alloc_helper"), false);
- LLVMValueRef fn_val = LLVMAddFunction(g->module, buf_ptr(fn_name), fn_type_ref);
- LLVMSetLinkage(fn_val, LLVMInternalLinkage);
- LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));
- addLLVMFnAttr(fn_val, "nounwind");
- addLLVMArgAttr(fn_val, (unsigned)0, "nonnull");
- addLLVMArgAttr(fn_val, (unsigned)1, "nonnull");
-
- LLVMBasicBlockRef prev_block = LLVMGetInsertBlock(g->builder);
- LLVMValueRef prev_debug_location = LLVMGetCurrentDebugLocation(g->builder);
- ZigFn *prev_cur_fn = g->cur_fn;
- LLVMValueRef prev_cur_fn_val = g->cur_fn_val;
-
- LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn_val, "Entry");
- LLVMPositionBuilderAtEnd(g->builder, entry_block);
- ZigLLVMClearCurrentDebugLocation(g->builder);
- g->cur_fn = nullptr;
- g->cur_fn_val = fn_val;
-
- LLVMValueRef sret_ptr = LLVMBuildAlloca(g->builder, LLVMGetElementType(alloc_fn_arg_types[0]), "");
-
- size_t next_arg = 0;
- LLVMValueRef realloc_fn_val = LLVMGetParam(fn_val, next_arg);
- next_arg += 1;
-
- LLVMValueRef stack_trace_val;
- if (g->have_err_ret_tracing) {
- stack_trace_val = LLVMGetParam(fn_val, next_arg);
- next_arg += 1;
- }
-
- LLVMValueRef allocator_val = LLVMGetParam(fn_val, next_arg);
- next_arg += 1;
- LLVMValueRef err_code_ptr = LLVMGetParam(fn_val, next_arg);
- next_arg += 1;
- LLVMValueRef coro_size = LLVMGetParam(fn_val, next_arg);
- next_arg += 1;
- LLVMValueRef alignment_val = LLVMConstInt(g->builtin_types.entry_u29->llvm_type,
- get_coro_frame_align_bytes(g), false);
-
- ConstExprValue *zero_array = create_const_str_lit(g, buf_create_from_str(""));
- ConstExprValue *undef_slice_zero = create_const_slice(g, zero_array, 0, 0, false);
- render_const_val(g, undef_slice_zero, "");
- render_const_val_global(g, undef_slice_zero, "");
-
- ZigList args = {};
- args.append(sret_ptr);
- if (g->have_err_ret_tracing) {
- args.append(stack_trace_val);
- }
- args.append(allocator_val);
- args.append(undef_slice_zero->global_refs->llvm_global);
- args.append(LLVMGetUndef(g->builtin_types.entry_u29->llvm_type));
- args.append(coro_size);
- args.append(alignment_val);
- LLVMValueRef call_instruction = ZigLLVMBuildCall(g->builder, realloc_fn_val, args.items, args.length,
- get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_FnInlineAuto, "");
- set_call_instr_sret(g, call_instruction);
- LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, sret_ptr, err_union_err_index, "");
- LLVMValueRef err_val = LLVMBuildLoad(g->builder, err_val_ptr, "");
- LLVMBuildStore(g->builder, err_val, err_code_ptr);
- LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, err_val, LLVMConstNull(LLVMTypeOf(err_val)), "");
- LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(fn_val, "AllocOk");
- LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(fn_val, "AllocFail");
- LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
-
- LLVMPositionBuilderAtEnd(g->builder, ok_block);
- LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, sret_ptr, err_union_payload_index, "");
- ZigType *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, false, false,
- PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0, false);
- ZigType *slice_type = get_slice_type(g, u8_ptr_type);
- size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index].gen_index;
- LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, payload_ptr, ptr_field_index, "");
- LLVMValueRef ptr_val = LLVMBuildLoad(g->builder, ptr_field_ptr, "");
- LLVMBuildRet(g->builder, ptr_val);
-
- LLVMPositionBuilderAtEnd(g->builder, fail_block);
- LLVMBuildRet(g->builder, LLVMConstNull(LLVMPointerType(LLVMInt8Type(), 0)));
-
- g->cur_fn = prev_cur_fn;
- g->cur_fn_val = prev_cur_fn_val;
- LLVMPositionBuilderAtEnd(g->builder, prev_block);
- if (!g->strip_debug_symbols) {
- LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
- }
-
- g->coro_alloc_helper_fn_val = fn_val;
- return fn_val;
-}
-
-static LLVMValueRef ir_render_coro_alloc_helper(CodeGen *g, IrExecutable *executable,
- IrInstructionCoroAllocHelper *instruction)
-{
- LLVMValueRef realloc_fn = ir_llvm_value(g, instruction->realloc_fn);
- LLVMValueRef coro_size = ir_llvm_value(g, instruction->coro_size);
- LLVMValueRef fn_val = get_coro_alloc_helper_fn_val(g, LLVMTypeOf(realloc_fn), instruction->realloc_fn->value.type);
- size_t err_code_ptr_arg_index = get_async_err_code_arg_index(g, &g->cur_fn->type_entry->data.fn.fn_type_id);
- size_t allocator_arg_index = get_async_allocator_arg_index(g, &g->cur_fn->type_entry->data.fn.fn_type_id);
-
- ZigList params = {};
- params.append(realloc_fn);
- uint32_t err_ret_trace_arg_index = get_err_ret_trace_arg_index(g, g->cur_fn);
- if (err_ret_trace_arg_index != UINT32_MAX) {
- params.append(LLVMGetParam(g->cur_fn_val, err_ret_trace_arg_index));
- }
- params.append(LLVMGetParam(g->cur_fn_val, allocator_arg_index));
- params.append(LLVMGetParam(g->cur_fn_val, err_code_ptr_arg_index));
- params.append(coro_size);
-
- return ZigLLVMBuildCall(g->builder, fn_val, params.items, params.length,
- get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_FnInlineAuto, "");
-}
-
static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutable *executable,
IrInstructionAtomicRmw *instruction)
{
@@ -5402,19 +4798,6 @@ static LLVMValueRef ir_render_atomic_load(CodeGen *g, IrExecutable *executable,
return load_inst;
}
-static LLVMValueRef ir_render_merge_err_ret_traces(CodeGen *g, IrExecutable *executable,
- IrInstructionMergeErrRetTraces *instruction)
-{
- assert(g->have_err_ret_tracing);
-
- LLVMValueRef src_trace_ptr = ir_llvm_value(g, instruction->src_err_ret_trace_ptr);
- LLVMValueRef dest_trace_ptr = ir_llvm_value(g, instruction->dest_err_ret_trace_ptr);
-
- LLVMValueRef args[] = { dest_trace_ptr, src_trace_ptr };
- ZigLLVMBuildCall(g->builder, get_merge_err_ret_traces_fn_val(g), args, 2, get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_FnInlineAuto, "");
- return nullptr;
-}
-
static LLVMValueRef ir_render_mark_err_ret_trace_ptr(CodeGen *g, IrExecutable *executable,
IrInstructionMarkErrRetTracePtr *instruction)
{
@@ -5559,7 +4942,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
case IrInstructionIdSetRuntimeSafety:
case IrInstructionIdSetFloatMode:
case IrInstructionIdArrayType:
- case IrInstructionIdPromiseType:
case IrInstructionIdSliceType:
case IrInstructionIdSizeOf:
case IrInstructionIdSwitchTarget:
@@ -5599,8 +4981,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
case IrInstructionIdTagType:
case IrInstructionIdExport:
case IrInstructionIdErrorUnion:
- case IrInstructionIdPromiseResultType:
- case IrInstructionIdAwaitBookkeeping:
case IrInstructionIdAddImplicitReturnType:
case IrInstructionIdIntCast:
case IrInstructionIdFloatCast:
@@ -5757,40 +5137,12 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
return ir_render_error_return_trace(g, executable, (IrInstructionErrorReturnTrace *)instruction);
case IrInstructionIdCancel:
return ir_render_cancel(g, executable, (IrInstructionCancel *)instruction);
- case IrInstructionIdGetImplicitAllocator:
- return ir_render_get_implicit_allocator(g, executable, (IrInstructionGetImplicitAllocator *)instruction);
- case IrInstructionIdCoroId:
- return ir_render_coro_id(g, executable, (IrInstructionCoroId *)instruction);
- case IrInstructionIdCoroAlloc:
- return ir_render_coro_alloc(g, executable, (IrInstructionCoroAlloc *)instruction);
- case IrInstructionIdCoroSize:
- return ir_render_coro_size(g, executable, (IrInstructionCoroSize *)instruction);
- case IrInstructionIdCoroBegin:
- return ir_render_coro_begin(g, executable, (IrInstructionCoroBegin *)instruction);
- case IrInstructionIdCoroAllocFail:
- return ir_render_coro_alloc_fail(g, executable, (IrInstructionCoroAllocFail *)instruction);
- case IrInstructionIdCoroSuspend:
- return ir_render_coro_suspend(g, executable, (IrInstructionCoroSuspend *)instruction);
- case IrInstructionIdCoroEnd:
- return ir_render_coro_end(g, executable, (IrInstructionCoroEnd *)instruction);
- case IrInstructionIdCoroFree:
- return ir_render_coro_free(g, executable, (IrInstructionCoroFree *)instruction);
- case IrInstructionIdCoroResume:
- return ir_render_coro_resume(g, executable, (IrInstructionCoroResume *)instruction);
- case IrInstructionIdCoroSave:
- return ir_render_coro_save(g, executable, (IrInstructionCoroSave *)instruction);
- case IrInstructionIdCoroPromise:
- return ir_render_coro_promise(g, executable, (IrInstructionCoroPromise *)instruction);
- case IrInstructionIdCoroAllocHelper:
- return ir_render_coro_alloc_helper(g, executable, (IrInstructionCoroAllocHelper *)instruction);
case IrInstructionIdAtomicRmw:
return ir_render_atomic_rmw(g, executable, (IrInstructionAtomicRmw *)instruction);
case IrInstructionIdAtomicLoad:
return ir_render_atomic_load(g, executable, (IrInstructionAtomicLoad *)instruction);
case IrInstructionIdSaveErrRetAddr:
return ir_render_save_err_ret_addr(g, executable, (IrInstructionSaveErrRetAddr *)instruction);
- case IrInstructionIdMergeErrRetTraces:
- return ir_render_merge_err_ret_traces(g, executable, (IrInstructionMergeErrRetTraces *)instruction);
case IrInstructionIdMarkErrRetTracePtr:
return ir_render_mark_err_ret_trace_ptr(g, executable, (IrInstructionMarkErrRetTracePtr *)instruction);
case IrInstructionIdFloatOp:
@@ -6008,7 +5360,6 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con
case ZigTypeIdPointer:
case ZigTypeIdFn:
case ZigTypeIdOptional:
- case ZigTypeIdPromise:
{
LLVMValueRef ptr_val = gen_const_val(g, const_val, "");
LLVMValueRef ptr_size_int_val = LLVMConstPtrToInt(ptr_val, g->builtin_types.entry_usize->llvm_type);
@@ -6591,7 +5942,6 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdOpaque:
- case ZigTypeIdPromise:
zig_unreachable();
}
@@ -7294,13 +6644,6 @@ static void define_builtin_types(CodeGen *g) {
g->primitive_type_table.put(&entry->name, entry);
}
- {
- ZigType *entry = get_promise_type(g, nullptr);
- g->primitive_type_table.put(&entry->name, entry);
- entry->size_in_bits = g->builtin_types.entry_usize->size_in_bits;
- entry->abi_align = g->builtin_types.entry_usize->abi_align;
- entry->abi_size = g->builtin_types.entry_usize->abi_size;
- }
}
@@ -7729,7 +7072,6 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
" BoundFn: Fn,\n"
" ArgTuple: void,\n"
" Opaque: void,\n"
- " Promise: Promise,\n"
" Vector: Vector,\n"
" EnumLiteral: void,\n"
"\n\n"
@@ -7842,14 +7184,9 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
" is_generic: bool,\n"
" is_var_args: bool,\n"
" return_type: ?type,\n"
- " async_allocator_type: ?type,\n"
" args: []FnArg,\n"
" };\n"
"\n"
- " pub const Promise = struct {\n"
- " child: ?type,\n"
- " };\n"
- "\n"
" pub const Vector = struct {\n"
" len: comptime_int,\n"
" child: type,\n"
@@ -8998,7 +8335,6 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_e
case ZigTypeIdArgTuple:
case ZigTypeIdErrorUnion:
case ZigTypeIdErrorSet:
- case ZigTypeIdPromise:
zig_unreachable();
case ZigTypeIdVoid:
case ZigTypeIdUnreachable:
@@ -9182,7 +8518,6 @@ static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_bu
case ZigTypeIdUndefined:
case ZigTypeIdNull:
case ZigTypeIdArgTuple:
- case ZigTypeIdPromise:
zig_unreachable();
}
}
@@ -9349,7 +8684,6 @@ static void gen_h_file(CodeGen *g) {
case ZigTypeIdArgTuple:
case ZigTypeIdOptional:
case ZigTypeIdFn:
- case ZigTypeIdPromise:
case ZigTypeIdVector:
zig_unreachable();
case ZigTypeIdEnum:
diff --git a/src/ir.cpp b/src/ir.cpp
index be7a8e2e51..f23fe1b7d0 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -99,7 +99,6 @@ struct ConstCastOnly {
ConstCastErrUnionErrSetMismatch *error_union_error_set;
ConstCastTypeMismatch *type_mismatch;
ConstCastOnly *return_type;
- ConstCastOnly *async_allocator_type;
ConstCastOnly *null_wrap_ptr_child;
ConstCastArg fn_arg;
ConstCastArgNoAlias arg_no_alias;
@@ -318,7 +317,6 @@ static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) {
case ZigTypeIdUnion:
case ZigTypeIdFn:
case ZigTypeIdArgTuple:
- case ZigTypeIdPromise:
case ZigTypeIdVector:
return false;
}
@@ -564,10 +562,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayType *) {
return IrInstructionIdArrayType;
}
-static constexpr IrInstructionId ir_instruction_id(IrInstructionPromiseType *) {
- return IrInstructionIdPromiseType;
-}
-
static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceType *) {
return IrInstructionIdSliceType;
}
@@ -964,58 +958,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCancel *) {
return IrInstructionIdCancel;
}
-static constexpr IrInstructionId ir_instruction_id(IrInstructionGetImplicitAllocator *) {
- return IrInstructionIdGetImplicitAllocator;
-}
-
-static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroId *) {
- return IrInstructionIdCoroId;
-}
-
-static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroAlloc *) {
- return IrInstructionIdCoroAlloc;
-}
-
-static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroSize *) {
- return IrInstructionIdCoroSize;
-}
-
-static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroBegin *) {
- return IrInstructionIdCoroBegin;
-}
-
-static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroAllocFail *) {
- return IrInstructionIdCoroAllocFail;
-}
-
-static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroSuspend *) {
- return IrInstructionIdCoroSuspend;
-}
-
-static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroEnd *) {
- return IrInstructionIdCoroEnd;
-}
-
-static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroFree *) {
- return IrInstructionIdCoroFree;
-}
-
-static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroResume *) {
- return IrInstructionIdCoroResume;
-}
-
-static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroSave *) {
- return IrInstructionIdCoroSave;
-}
-
-static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroPromise *) {
- return IrInstructionIdCoroPromise;
-}
-
-static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroAllocHelper *) {
- return IrInstructionIdCoroAllocHelper;
-}
-
static constexpr IrInstructionId ir_instruction_id(IrInstructionAtomicRmw *) {
return IrInstructionIdAtomicRmw;
}
@@ -1024,14 +966,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAtomicLoad *) {
return IrInstructionIdAtomicLoad;
}
-static constexpr IrInstructionId ir_instruction_id(IrInstructionPromiseResultType *) {
- return IrInstructionIdPromiseResultType;
-}
-
-static constexpr IrInstructionId ir_instruction_id(IrInstructionAwaitBookkeeping *) {
- return IrInstructionIdAwaitBookkeeping;
-}
-
static constexpr IrInstructionId ir_instruction_id(IrInstructionSaveErrRetAddr *) {
return IrInstructionIdSaveErrRetAddr;
}
@@ -1040,10 +974,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAddImplicitRetur
return IrInstructionIdAddImplicitReturnType;
}
-static constexpr IrInstructionId ir_instruction_id(IrInstructionMergeErrRetTraces *) {
- return IrInstructionIdMergeErrRetTraces;
-}
-
static constexpr IrInstructionId ir_instruction_id(IrInstructionMarkErrRetTracePtr *) {
return IrInstructionIdMarkErrRetTracePtr;
}
@@ -1213,14 +1143,6 @@ static IrInstruction *ir_build_const_usize(IrBuilder *irb, Scope *scope, AstNode
return &const_instruction->base;
}
-static IrInstruction *ir_build_const_u8(IrBuilder *irb, Scope *scope, AstNode *source_node, uint8_t value) {
- IrInstructionConst *const_instruction = ir_build_instruction(irb, scope, source_node);
- const_instruction->base.value.type = irb->codegen->builtin_types.entry_u8;
- const_instruction->base.value.special = ConstValSpecialStatic;
- bigint_init_unsigned(&const_instruction->base.value.data.x_bigint, value);
- return &const_instruction->base;
-}
-
static IrInstruction *ir_create_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
ZigType *type_entry)
{
@@ -1428,7 +1350,7 @@ static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, Ast
static IrInstruction *ir_build_call_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args,
- bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator,
+ bool is_comptime, FnInline fn_inline, bool is_async,
IrInstruction *new_stack, ResultLoc *result_loc)
{
IrInstructionCallSrc *call_instruction = ir_build_instruction(irb, scope, source_node);
@@ -1439,14 +1361,12 @@ static IrInstruction *ir_build_call_src(IrBuilder *irb, Scope *scope, AstNode *s
call_instruction->args = args;
call_instruction->arg_count = arg_count;
call_instruction->is_async = is_async;
- call_instruction->async_allocator = async_allocator;
call_instruction->new_stack = new_stack;
call_instruction->result_loc = result_loc;
if (fn_ref != nullptr) ir_ref_instruction(fn_ref, irb->current_basic_block);
for (size_t i = 0; i < arg_count; i += 1)
ir_ref_instruction(args[i], irb->current_basic_block);
- if (async_allocator != nullptr) ir_ref_instruction(async_allocator, irb->current_basic_block);
if (new_stack != nullptr) ir_ref_instruction(new_stack, irb->current_basic_block);
return &call_instruction->base;
@@ -1454,7 +1374,7 @@ static IrInstruction *ir_build_call_src(IrBuilder *irb, Scope *scope, AstNode *s
static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_instruction,
ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args,
- FnInline fn_inline, bool is_async, IrInstruction *async_allocator, IrInstruction *new_stack,
+ FnInline fn_inline, bool is_async, IrInstruction *new_stack,
IrInstruction *result_loc, ZigType *return_type)
{
IrInstructionCallGen *call_instruction = ir_build_instruction(&ira->new_irb,
@@ -1466,14 +1386,12 @@ static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_in
call_instruction->args = args;
call_instruction->arg_count = arg_count;
call_instruction->is_async = is_async;
- call_instruction->async_allocator = async_allocator;
call_instruction->new_stack = new_stack;
call_instruction->result_loc = result_loc;
if (fn_ref != nullptr) ir_ref_instruction(fn_ref, ira->new_irb.current_basic_block);
for (size_t i = 0; i < arg_count; i += 1)
ir_ref_instruction(args[i], ira->new_irb.current_basic_block);
- if (async_allocator != nullptr) ir_ref_instruction(async_allocator, ira->new_irb.current_basic_block);
if (new_stack != nullptr) ir_ref_instruction(new_stack, ira->new_irb.current_basic_block);
if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
@@ -1753,17 +1671,6 @@ static IrInstruction *ir_build_array_type(IrBuilder *irb, Scope *scope, AstNode
return &instruction->base;
}
-static IrInstruction *ir_build_promise_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
- IrInstruction *payload_type)
-{
- IrInstructionPromiseType *instruction = ir_build_instruction(irb, scope, source_node);
- instruction->payload_type = payload_type;
-
- if (payload_type != nullptr) ir_ref_instruction(payload_type, irb->current_basic_block);
-
- return &instruction->base;
-}
-
static IrInstruction *ir_build_slice_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
IrInstruction *child_type, bool is_const, bool is_volatile, IrInstruction *align_value, bool is_allow_zero)
{
@@ -2595,13 +2502,12 @@ static IrInstruction *ir_build_unwrap_err_payload(IrBuilder *irb, Scope *scope,
static IrInstruction *ir_build_fn_proto(IrBuilder *irb, Scope *scope, AstNode *source_node,
IrInstruction **param_types, IrInstruction *align_value, IrInstruction *return_type,
- IrInstruction *async_allocator_type_value, bool is_var_args)
+ bool is_var_args)
{
IrInstructionFnProto *instruction = ir_build_instruction(irb, scope, source_node);
instruction->param_types = param_types;
instruction->align_value = align_value;
instruction->return_type = return_type;
- instruction->async_allocator_type_value = async_allocator_type_value;
instruction->is_var_args = is_var_args;
assert(source_node->type == NodeTypeFnProto);
@@ -2611,7 +2517,6 @@ static IrInstruction *ir_build_fn_proto(IrBuilder *irb, Scope *scope, AstNode *s
if (param_types[i] != nullptr) ir_ref_instruction(param_types[i], irb->current_basic_block);
}
if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block);
- if (async_allocator_type_value != nullptr) ir_ref_instruction(async_allocator_type_value, irb->current_basic_block);
ir_ref_instruction(return_type, irb->current_basic_block);
return &instruction->base;
@@ -3055,149 +2960,6 @@ static IrInstruction *ir_build_error_union(IrBuilder *irb, Scope *scope, AstNode
return &instruction->base;
}
-static IrInstruction *ir_build_cancel(IrBuilder *irb, Scope *scope, AstNode *source_node,
- IrInstruction *target)
-{
- IrInstructionCancel *instruction = ir_build_instruction(irb, scope, source_node);
- instruction->target = target;
-
- ir_ref_instruction(target, irb->current_basic_block);
-
- return &instruction->base;
-}
-
-static IrInstruction *ir_build_get_implicit_allocator(IrBuilder *irb, Scope *scope, AstNode *source_node,
- ImplicitAllocatorId id)
-{
- IrInstructionGetImplicitAllocator *instruction = ir_build_instruction(irb, scope, source_node);
- instruction->id = id;
-
- return &instruction->base;
-}
-
-static IrInstruction *ir_build_coro_id(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *promise_ptr) {
- IrInstructionCoroId *instruction = ir_build_instruction(irb, scope, source_node);
- instruction->promise_ptr = promise_ptr;
-
- ir_ref_instruction(promise_ptr, irb->current_basic_block);
-
- return &instruction->base;
-}
-
-static IrInstruction *ir_build_coro_alloc(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *coro_id) {
- IrInstructionCoroAlloc *instruction = ir_build_instruction(irb, scope, source_node);
- instruction->coro_id = coro_id;
-
- ir_ref_instruction(coro_id, irb->current_basic_block);
-
- return &instruction->base;
-}
-
-static IrInstruction *ir_build_coro_size(IrBuilder *irb, Scope *scope, AstNode *source_node) {
- IrInstructionCoroSize *instruction = ir_build_instruction(irb, scope, source_node);
-
- return &instruction->base;
-}
-
-static IrInstruction *ir_build_coro_begin(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *coro_id, IrInstruction *coro_mem_ptr) {
- IrInstructionCoroBegin *instruction = ir_build_instruction(irb, scope, source_node);
- instruction->coro_id = coro_id;
- instruction->coro_mem_ptr = coro_mem_ptr;
-
- ir_ref_instruction(coro_id, irb->current_basic_block);
- ir_ref_instruction(coro_mem_ptr, irb->current_basic_block);
-
- return &instruction->base;
-}
-
-static IrInstruction *ir_build_coro_alloc_fail(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *err_val) {
- IrInstructionCoroAllocFail *instruction = ir_build_instruction(irb, scope, source_node);
- instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable;
- instruction->base.value.special = ConstValSpecialStatic;
- instruction->err_val = err_val;
-
- ir_ref_instruction(err_val, irb->current_basic_block);
-
- return &instruction->base;
-}
-
-static IrInstruction *ir_build_coro_suspend(IrBuilder *irb, Scope *scope, AstNode *source_node,
- IrInstruction *save_point, IrInstruction *is_final)
-{
- IrInstructionCoroSuspend *instruction = ir_build_instruction(irb, scope, source_node);
- instruction->save_point = save_point;
- instruction->is_final = is_final;
-
- if (save_point != nullptr) ir_ref_instruction(save_point, irb->current_basic_block);
- ir_ref_instruction(is_final, irb->current_basic_block);
-
- return &instruction->base;
-}
-
-static IrInstruction *ir_build_coro_end(IrBuilder *irb, Scope *scope, AstNode *source_node) {
- IrInstructionCoroEnd *instruction = ir_build_instruction(irb, scope, source_node);
- return &instruction->base;
-}
-
-static IrInstruction *ir_build_coro_free(IrBuilder *irb, Scope *scope, AstNode *source_node,
- IrInstruction *coro_id, IrInstruction *coro_handle)
-{
- IrInstructionCoroFree *instruction = ir_build_instruction(irb, scope, source_node);
- instruction->coro_id = coro_id;
- instruction->coro_handle = coro_handle;
-
- ir_ref_instruction(coro_id, irb->current_basic_block);
- ir_ref_instruction(coro_handle, irb->current_basic_block);
-
- return &instruction->base;
-}
-
-static IrInstruction *ir_build_coro_resume(IrBuilder *irb, Scope *scope, AstNode *source_node,
- IrInstruction *awaiter_handle)
-{
- IrInstructionCoroResume *instruction = ir_build_instruction(irb, scope, source_node);
- instruction->awaiter_handle = awaiter_handle;
-
- ir_ref_instruction(awaiter_handle, irb->current_basic_block);
-
- return &instruction->base;
-}
-
-static IrInstruction *ir_build_coro_save(IrBuilder *irb, Scope *scope, AstNode *source_node,
- IrInstruction *coro_handle)
-{
- IrInstructionCoroSave *instruction = ir_build_instruction(irb, scope, source_node);
- instruction->coro_handle = coro_handle;
-
- ir_ref_instruction(coro_handle, irb->current_basic_block);
-
- return &instruction->base;
-}
-
-static IrInstruction *ir_build_coro_promise(IrBuilder *irb, Scope *scope, AstNode *source_node,
- IrInstruction *coro_handle)
-{
- IrInstructionCoroPromise *instruction = ir_build_instruction(irb, scope, source_node);
- instruction->coro_handle = coro_handle;
-
- ir_ref_instruction(coro_handle, irb->current_basic_block);
-
- return &instruction->base;
-}
-
-static IrInstruction *ir_build_coro_alloc_helper(IrBuilder *irb, Scope *scope, AstNode *source_node,
- IrInstruction *realloc_fn, IrInstruction *coro_size)
-{
- IrInstructionCoroAllocHelper *instruction = ir_build_instruction(irb, scope, source_node);
- instruction->realloc_fn = realloc_fn;
- instruction->coro_size = coro_size;
-
- ir_ref_instruction(realloc_fn, irb->current_basic_block);
- ir_ref_instruction(coro_size, irb->current_basic_block);
-
- return &instruction->base;
-}
-
static IrInstruction *ir_build_atomic_rmw(IrBuilder *irb, Scope *scope, AstNode *source_node,
IrInstruction *operand_type, IrInstruction *ptr, IrInstruction *op, IrInstruction *operand,
IrInstruction *ordering, AtomicRmwOp resolved_op, AtomicOrder resolved_ordering)
@@ -3237,28 +2999,6 @@ static IrInstruction *ir_build_atomic_load(IrBuilder *irb, Scope *scope, AstNode
return &instruction->base;
}
-static IrInstruction *ir_build_promise_result_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
- IrInstruction *promise_type)
-{
- IrInstructionPromiseResultType *instruction = ir_build_instruction(irb, scope, source_node);
- instruction->promise_type = promise_type;
-
- ir_ref_instruction(promise_type, irb->current_basic_block);
-
- return &instruction->base;
-}
-
-static IrInstruction *ir_build_await_bookkeeping(IrBuilder *irb, Scope *scope, AstNode *source_node,
- IrInstruction *promise_result_type)
-{
- IrInstructionAwaitBookkeeping *instruction = ir_build_instruction(irb, scope, source_node);
- instruction->promise_result_type = promise_result_type;
-
- ir_ref_instruction(promise_result_type, irb->current_basic_block);
-
- return &instruction->base;
-}
-
static IrInstruction *ir_build_save_err_ret_addr(IrBuilder *irb, Scope *scope, AstNode *source_node) {
IrInstructionSaveErrRetAddr *instruction = ir_build_instruction(irb, scope, source_node);
return &instruction->base;
@@ -3275,21 +3015,6 @@ static IrInstruction *ir_build_add_implicit_return_type(IrBuilder *irb, Scope *s
return &instruction->base;
}
-static IrInstruction *ir_build_merge_err_ret_traces(IrBuilder *irb, Scope *scope, AstNode *source_node,
- IrInstruction *coro_promise_ptr, IrInstruction *src_err_ret_trace_ptr, IrInstruction *dest_err_ret_trace_ptr)
-{
- IrInstructionMergeErrRetTraces *instruction = ir_build_instruction(irb, scope, source_node);
- instruction->coro_promise_ptr = coro_promise_ptr;
- instruction->src_err_ret_trace_ptr = src_err_ret_trace_ptr;
- instruction->dest_err_ret_trace_ptr = dest_err_ret_trace_ptr;
-
- ir_ref_instruction(coro_promise_ptr, irb->current_basic_block);
- ir_ref_instruction(src_err_ret_trace_ptr, irb->current_basic_block);
- ir_ref_instruction(dest_err_ret_trace_ptr, irb->current_basic_block);
-
- return &instruction->base;
-}
-
static IrInstruction *ir_build_mark_err_ret_trace_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *err_ret_trace_ptr) {
IrInstructionMarkErrRetTracePtr *instruction = ir_build_instruction(irb, scope, source_node);
instruction->err_ret_trace_ptr = err_ret_trace_ptr;
@@ -3488,7 +3213,6 @@ static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_sco
continue;
case ScopeIdDeferExpr:
case ScopeIdCImport:
- case ScopeIdCoroPrelude:
zig_unreachable();
}
}
@@ -3544,7 +3268,6 @@ static bool ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *o
continue;
case ScopeIdDeferExpr:
case ScopeIdCImport:
- case ScopeIdCoroPrelude:
zig_unreachable();
}
}
@@ -3563,18 +3286,6 @@ static void ir_set_cursor_at_end_and_append_block(IrBuilder *irb, IrBasicBlock *
ir_set_cursor_at_end(irb, basic_block);
}
-static ScopeSuspend *get_scope_suspend(Scope *scope) {
- while (scope) {
- if (scope->id == ScopeIdSuspend)
- return (ScopeSuspend *)scope;
- if (scope->id == ScopeIdFnDef)
- return nullptr;
-
- scope = scope->parent;
- }
- return nullptr;
-}
-
static ScopeDeferExpr *get_scope_defer_expr(Scope *scope) {
while (scope) {
if (scope->id == ScopeIdDeferExpr)
@@ -3604,47 +3315,7 @@ static IrInstruction *ir_gen_async_return(IrBuilder *irb, Scope *scope, AstNode
return return_inst;
}
- IrBasicBlock *suspended_block = ir_create_basic_block(irb, scope, "Suspended");
- IrBasicBlock *not_suspended_block = ir_create_basic_block(irb, scope, "NotSuspended");
- IrBasicBlock *store_awaiter_block = ir_create_basic_block(irb, scope, "StoreAwaiter");
- IrBasicBlock *check_canceled_block = ir_create_basic_block(irb, scope, "CheckCanceled");
-
- IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, scope, node, 0x7); // 0b111
- IrInstruction *ptr_mask = ir_build_un_op(irb, scope, node, IrUnOpBinNot, inverted_ptr_mask); // 0b111...000
- IrInstruction *is_canceled_mask = ir_build_const_usize(irb, scope, node, 0x1); // 0b001
- IrInstruction *is_suspended_mask = ir_build_const_usize(irb, scope, node, 0x2); // 0b010
- IrInstruction *promise_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_promise);
- IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, false);
- IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0);
-
- ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_field_ptr, return_value);
- IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize);
- IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node,
- usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, ptr_mask, nullptr,
- AtomicRmwOp_or, AtomicOrderSeqCst);
-
- IrInstruction *is_suspended_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_suspended_mask, false);
- IrInstruction *is_suspended_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_suspended_value, zero, false);
- ir_build_cond_br(irb, scope, node, is_suspended_bool, suspended_block, not_suspended_block, is_comptime);
-
- ir_set_cursor_at_end_and_append_block(irb, suspended_block);
- ir_build_unreachable(irb, scope, node);
-
- ir_set_cursor_at_end_and_append_block(irb, not_suspended_block);
- IrInstruction *await_handle_addr = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, ptr_mask, false);
- // if we ever add null checking safety to the ptrtoint instruction, it needs to be disabled here
- IrInstruction *have_await_handle = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, await_handle_addr, zero, false);
- ir_build_cond_br(irb, scope, node, have_await_handle, store_awaiter_block, check_canceled_block, is_comptime);
-
- ir_set_cursor_at_end_and_append_block(irb, store_awaiter_block);
- IrInstruction *await_handle = ir_build_int_to_ptr(irb, scope, node, promise_type_val, await_handle_addr);
- ir_build_store_ptr(irb, scope, node, irb->exec->await_handle_var_ptr, await_handle);
- ir_build_br(irb, scope, node, irb->exec->coro_normal_final, is_comptime);
-
- ir_set_cursor_at_end_and_append_block(irb, check_canceled_block);
- IrInstruction *is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false);
- IrInstruction *is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false);
- return ir_build_cond_br(irb, scope, node, is_canceled_bool, irb->exec->coro_final_cleanup_block, irb->exec->coro_early_final, is_comptime);
+ zig_panic("TODO async return");
}
static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) {
@@ -5386,7 +5057,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
FnInline fn_inline = (builtin_fn->id == BuiltinFnIdInlineCall) ? FnInlineAlways : FnInlineNever;
IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false,
- fn_inline, false, nullptr, nullptr, result_loc);
+ fn_inline, false, nullptr, result_loc);
return ir_lval_wrap(irb, scope, call, lval, result_loc);
}
case BuiltinFnIdNewStackCall:
@@ -5417,7 +5088,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
}
IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false,
- FnInlineAuto, false, nullptr, new_stack, result_loc);
+ FnInlineAuto, false, new_stack, result_loc);
return ir_lval_wrap(irb, scope, call, lval, result_loc);
}
case BuiltinFnIdTypeId:
@@ -5722,17 +5393,12 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node
}
bool is_async = node->data.fn_call_expr.is_async;
- IrInstruction *async_allocator = nullptr;
if (is_async) {
- if (node->data.fn_call_expr.async_allocator) {
- async_allocator = ir_gen_node(irb, node->data.fn_call_expr.async_allocator, scope);
- if (async_allocator == irb->codegen->invalid_instruction)
- return async_allocator;
- }
+ zig_panic("TODO async fn call");
}
IrInstruction *fn_call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto,
- is_async, async_allocator, nullptr, result_loc);
+ is_async, nullptr, result_loc);
return ir_lval_wrap(irb, scope, fn_call, lval, result_loc);
}
@@ -6751,22 +6417,6 @@ static IrInstruction *ir_gen_array_type(IrBuilder *irb, Scope *scope, AstNode *n
}
}
-static IrInstruction *ir_gen_promise_type(IrBuilder *irb, Scope *scope, AstNode *node) {
- assert(node->type == NodeTypePromiseType);
-
- AstNode *payload_type_node = node->data.promise_type.payload_type;
- IrInstruction *payload_type_value = nullptr;
-
- if (payload_type_node != nullptr) {
- payload_type_value = ir_gen_node(irb, payload_type_node, scope);
- if (payload_type_value == irb->codegen->invalid_instruction)
- return payload_type_value;
-
- }
-
- return ir_build_promise_type(irb, scope, node, payload_type_value);
-}
-
static IrInstruction *ir_gen_undefined_literal(IrBuilder *irb, Scope *scope, AstNode *node) {
assert(node->type == NodeTypeUndefinedLiteral);
return ir_build_const_undefined(irb, scope, node);
@@ -7969,87 +7619,7 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo
//return_type = nullptr;
}
- IrInstruction *async_allocator_type_value = nullptr;
- if (node->data.fn_proto.async_allocator_type != nullptr) {
- async_allocator_type_value = ir_gen_node(irb, node->data.fn_proto.async_allocator_type, parent_scope);
- if (async_allocator_type_value == irb->codegen->invalid_instruction)
- return irb->codegen->invalid_instruction;
- }
-
- return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, return_type,
- async_allocator_type_value, is_var_args);
-}
-
-static IrInstruction *ir_gen_cancel_target(IrBuilder *irb, Scope *scope, AstNode *node,
- IrInstruction *target_inst, bool cancel_non_suspended, bool cancel_awaited)
-{
- IrBasicBlock *done_block = ir_create_basic_block(irb, scope, "CancelDone");
- IrBasicBlock *not_canceled_block = ir_create_basic_block(irb, scope, "NotCanceled");
- IrBasicBlock *pre_return_block = ir_create_basic_block(irb, scope, "PreReturn");
- IrBasicBlock *post_return_block = ir_create_basic_block(irb, scope, "PostReturn");
- IrBasicBlock *do_cancel_block = ir_create_basic_block(irb, scope, "DoCancel");
-
- IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0);
- IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize);
- IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, false);
- IrInstruction *is_canceled_mask = ir_build_const_usize(irb, scope, node, 0x1); // 0b001
- IrInstruction *promise_T_type_val = ir_build_const_type(irb, scope, node,
- get_promise_type(irb->codegen, irb->codegen->builtin_types.entry_void));
- IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, scope, node, 0x7); // 0b111
- IrInstruction *ptr_mask = ir_build_un_op(irb, scope, node, IrUnOpBinNot, inverted_ptr_mask); // 0b111...000
- IrInstruction *await_mask = ir_build_const_usize(irb, scope, node, 0x4); // 0b100
- IrInstruction *is_suspended_mask = ir_build_const_usize(irb, scope, node, 0x2); // 0b010
-
- // TODO relies on Zig not re-ordering fields
- IrInstruction *casted_target_inst = ir_build_ptr_cast_src(irb, scope, node, promise_T_type_val, target_inst,
- false);
- IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, casted_target_inst);
- Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME);
- IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,
- atomic_state_field_name, false);
-
- // set the is_canceled bit
- IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node,
- usize_type_val, atomic_state_ptr, nullptr, is_canceled_mask, nullptr,
- AtomicRmwOp_or, AtomicOrderSeqCst);
-
- IrInstruction *is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false);
- IrInstruction *is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false);
- ir_build_cond_br(irb, scope, node, is_canceled_bool, done_block, not_canceled_block, is_comptime);
-
- ir_set_cursor_at_end_and_append_block(irb, not_canceled_block);
- IrInstruction *awaiter_addr = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, ptr_mask, false);
- IrInstruction *is_returned_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpEq, awaiter_addr, ptr_mask, false);
- ir_build_cond_br(irb, scope, node, is_returned_bool, post_return_block, pre_return_block, is_comptime);
-
- ir_set_cursor_at_end_and_append_block(irb, post_return_block);
- if (cancel_awaited) {
- ir_build_br(irb, scope, node, do_cancel_block, is_comptime);
- } else {
- IrInstruction *is_awaited_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, await_mask, false);
- IrInstruction *is_awaited_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_awaited_value, zero, false);
- ir_build_cond_br(irb, scope, node, is_awaited_bool, done_block, do_cancel_block, is_comptime);
- }
-
- ir_set_cursor_at_end_and_append_block(irb, pre_return_block);
- if (cancel_awaited) {
- if (cancel_non_suspended) {
- ir_build_br(irb, scope, node, do_cancel_block, is_comptime);
- } else {
- IrInstruction *is_suspended_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_suspended_mask, false);
- IrInstruction *is_suspended_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_suspended_value, zero, false);
- ir_build_cond_br(irb, scope, node, is_suspended_bool, do_cancel_block, done_block, is_comptime);
- }
- } else {
- ir_build_br(irb, scope, node, done_block, is_comptime);
- }
-
- ir_set_cursor_at_end_and_append_block(irb, do_cancel_block);
- ir_build_cancel(irb, scope, node, target_inst);
- ir_build_br(irb, scope, node, done_block, is_comptime);
-
- ir_set_cursor_at_end_and_append_block(irb, done_block);
- return ir_build_const_void(irb, scope, node);
+ return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, return_type, is_var_args);
}
static IrInstruction *ir_gen_cancel(IrBuilder *irb, Scope *scope, AstNode *node) {
@@ -8059,57 +7629,7 @@ static IrInstruction *ir_gen_cancel(IrBuilder *irb, Scope *scope, AstNode *node)
if (target_inst == irb->codegen->invalid_instruction)
return irb->codegen->invalid_instruction;
- return ir_gen_cancel_target(irb, scope, node, target_inst, false, true);
-}
-
-static IrInstruction *ir_gen_resume_target(IrBuilder *irb, Scope *scope, AstNode *node,
- IrInstruction *target_inst)
-{
- IrBasicBlock *done_block = ir_create_basic_block(irb, scope, "ResumeDone");
- IrBasicBlock *not_canceled_block = ir_create_basic_block(irb, scope, "NotCanceled");
- IrBasicBlock *suspended_block = ir_create_basic_block(irb, scope, "IsSuspended");
- IrBasicBlock *not_suspended_block = ir_create_basic_block(irb, scope, "IsNotSuspended");
-
- IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0);
- IrInstruction *is_canceled_mask = ir_build_const_usize(irb, scope, node, 0x1); // 0b001
- IrInstruction *is_suspended_mask = ir_build_const_usize(irb, scope, node, 0x2); // 0b010
- IrInstruction *and_mask = ir_build_un_op(irb, scope, node, IrUnOpBinNot, is_suspended_mask);
- IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, false);
- IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize);
- IrInstruction *promise_T_type_val = ir_build_const_type(irb, scope, node,
- get_promise_type(irb->codegen, irb->codegen->builtin_types.entry_void));
-
- // TODO relies on Zig not re-ordering fields
- IrInstruction *casted_target_inst = ir_build_ptr_cast_src(irb, scope, node, promise_T_type_val, target_inst,
- false);
- IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, casted_target_inst);
- Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME);
- IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,
- atomic_state_field_name, false);
-
- // clear the is_suspended bit
- IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node,
- usize_type_val, atomic_state_ptr, nullptr, and_mask, nullptr,
- AtomicRmwOp_and, AtomicOrderSeqCst);
-
- IrInstruction *is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false);
- IrInstruction *is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false);
- ir_build_cond_br(irb, scope, node, is_canceled_bool, done_block, not_canceled_block, is_comptime);
-
- ir_set_cursor_at_end_and_append_block(irb, not_canceled_block);
- IrInstruction *is_suspended_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_suspended_mask, false);
- IrInstruction *is_suspended_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_suspended_value, zero, false);
- ir_build_cond_br(irb, scope, node, is_suspended_bool, suspended_block, not_suspended_block, is_comptime);
-
- ir_set_cursor_at_end_and_append_block(irb, not_suspended_block);
- ir_build_unreachable(irb, scope, node);
-
- ir_set_cursor_at_end_and_append_block(irb, suspended_block);
- ir_build_coro_resume(irb, scope, node, target_inst);
- ir_build_br(irb, scope, node, done_block, is_comptime);
-
- ir_set_cursor_at_end_and_append_block(irb, done_block);
- return ir_build_const_void(irb, scope, node);
+ zig_panic("TODO ir_gen_cancel");
}
static IrInstruction *ir_gen_resume(IrBuilder *irb, Scope *scope, AstNode *node) {
@@ -8119,7 +7639,7 @@ static IrInstruction *ir_gen_resume(IrBuilder *irb, Scope *scope, AstNode *node)
if (target_inst == irb->codegen->invalid_instruction)
return irb->codegen->invalid_instruction;
- return ir_gen_resume_target(irb, scope, node, target_inst);
+ zig_panic("TODO ir_gen_resume");
}
static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *node) {
@@ -8129,298 +7649,13 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n
if (target_inst == irb->codegen->invalid_instruction)
return irb->codegen->invalid_instruction;
- ZigFn *fn_entry = exec_fn_entry(irb->exec);
- if (!fn_entry) {
- add_node_error(irb->codegen, node, buf_sprintf("await outside function definition"));
- return irb->codegen->invalid_instruction;
- }
- if (fn_entry->type_entry->data.fn.fn_type_id.cc != CallingConventionAsync) {
- add_node_error(irb->codegen, node, buf_sprintf("await in non-async function"));
- return irb->codegen->invalid_instruction;
- }
-
- ScopeDeferExpr *scope_defer_expr = get_scope_defer_expr(scope);
- if (scope_defer_expr) {
- if (!scope_defer_expr->reported_err) {
- add_node_error(irb->codegen, node, buf_sprintf("cannot await inside defer expression"));
- scope_defer_expr->reported_err = true;
- }
- return irb->codegen->invalid_instruction;
- }
-
- Scope *outer_scope = irb->exec->begin_scope;
-
- IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, target_inst);
- Buf *result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME);
- IrInstruction *result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name, false);
-
- if (irb->codegen->have_err_ret_tracing) {
- IrInstruction *err_ret_trace_ptr = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::NonNull);
- Buf *err_ret_trace_ptr_field_name = buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME);
- IrInstruction *err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name, false);
- ir_build_store_ptr(irb, scope, node, err_ret_trace_ptr_field_ptr, err_ret_trace_ptr);
- }
-
- IrBasicBlock *already_awaited_block = ir_create_basic_block(irb, scope, "AlreadyAwaited");
- IrBasicBlock *not_awaited_block = ir_create_basic_block(irb, scope, "NotAwaited");
- IrBasicBlock *not_canceled_block = ir_create_basic_block(irb, scope, "NotCanceled");
- IrBasicBlock *yes_suspend_block = ir_create_basic_block(irb, scope, "YesSuspend");
- IrBasicBlock *no_suspend_block = ir_create_basic_block(irb, scope, "NoSuspend");
- IrBasicBlock *merge_block = ir_create_basic_block(irb, scope, "MergeSuspend");
- IrBasicBlock *cleanup_block = ir_create_basic_block(irb, scope, "SuspendCleanup");
- IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "SuspendResume");
- IrBasicBlock *cancel_target_block = ir_create_basic_block(irb, scope, "CancelTarget");
- IrBasicBlock *do_cancel_block = ir_create_basic_block(irb, scope, "DoCancel");
- IrBasicBlock *do_defers_block = ir_create_basic_block(irb, scope, "DoDefers");
- IrBasicBlock *destroy_block = ir_create_basic_block(irb, scope, "DestroyBlock");
- IrBasicBlock *my_suspended_block = ir_create_basic_block(irb, scope, "AlreadySuspended");
- IrBasicBlock *my_not_suspended_block = ir_create_basic_block(irb, scope, "NotAlreadySuspended");
- IrBasicBlock *do_suspend_block = ir_create_basic_block(irb, scope, "DoSuspend");
-
- Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME);
- IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,
- atomic_state_field_name, false);
-
- IrInstruction *promise_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_promise);
- IrInstruction *const_bool_false = ir_build_const_bool(irb, scope, node, false);
- IrInstruction *undef = ir_build_const_undefined(irb, scope, node);
- IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize);
- IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0);
- IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, scope, node, 0x7); // 0b111
- IrInstruction *ptr_mask = ir_build_un_op(irb, scope, node, IrUnOpBinNot, inverted_ptr_mask); // 0b111...000
- IrInstruction *await_mask = ir_build_const_usize(irb, scope, node, 0x4); // 0b100
- IrInstruction *is_canceled_mask = ir_build_const_usize(irb, scope, node, 0x1); // 0b001
- IrInstruction *is_suspended_mask = ir_build_const_usize(irb, scope, node, 0x2); // 0b010
-
- ZigVar *result_var = ir_create_var(irb, node, scope, nullptr,
- false, false, true, const_bool_false);
- IrInstruction *target_promise_type = ir_build_typeof(irb, scope, node, target_inst);
- IrInstruction *promise_result_type = ir_build_promise_result_type(irb, scope, node, target_promise_type);
- ir_build_await_bookkeeping(irb, scope, node, promise_result_type);
- IrInstruction *undef_promise_result = ir_build_implicit_cast(irb, scope, node, promise_result_type, undef, nullptr);
- build_decl_var_and_init(irb, scope, node, result_var, undef_promise_result, "result", const_bool_false);
- IrInstruction *my_result_var_ptr = ir_build_var_ptr(irb, scope, node, result_var);
- ir_build_store_ptr(irb, scope, node, result_ptr_field_ptr, my_result_var_ptr);
- IrInstruction *save_token = ir_build_coro_save(irb, scope, node, irb->exec->coro_handle);
-
- IrInstruction *coro_handle_addr = ir_build_ptr_to_int(irb, scope, node, irb->exec->coro_handle);
- IrInstruction *mask_bits = ir_build_bin_op(irb, scope, node, IrBinOpBinOr, coro_handle_addr, await_mask, false);
- IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node,
- usize_type_val, atomic_state_ptr, nullptr, mask_bits, nullptr,
- AtomicRmwOp_or, AtomicOrderSeqCst);
-
- IrInstruction *is_awaited_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, await_mask, false);
- IrInstruction *is_awaited_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_awaited_value, zero, false);
- ir_build_cond_br(irb, scope, node, is_awaited_bool, already_awaited_block, not_awaited_block, const_bool_false);
-
- ir_set_cursor_at_end_and_append_block(irb, already_awaited_block);
- ir_build_unreachable(irb, scope, node);
-
- ir_set_cursor_at_end_and_append_block(irb, not_awaited_block);
- IrInstruction *await_handle_addr = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, ptr_mask, false);
- IrInstruction *is_non_null = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, await_handle_addr, zero, false);
- IrInstruction *is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false);
- IrInstruction *is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false);
- ir_build_cond_br(irb, scope, node, is_canceled_bool, cancel_target_block, not_canceled_block, const_bool_false);
-
- ir_set_cursor_at_end_and_append_block(irb, not_canceled_block);
- ir_build_cond_br(irb, scope, node, is_non_null, no_suspend_block, yes_suspend_block, const_bool_false);
-
- ir_set_cursor_at_end_and_append_block(irb, cancel_target_block);
- ir_build_cancel(irb, scope, node, target_inst);
- ir_mark_gen(ir_build_br(irb, scope, node, cleanup_block, const_bool_false));
-
- ir_set_cursor_at_end_and_append_block(irb, no_suspend_block);
- if (irb->codegen->have_err_ret_tracing) {
- Buf *err_ret_trace_field_name = buf_create_from_str(ERR_RET_TRACE_FIELD_NAME);
- IrInstruction *src_err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name, false);
- IrInstruction *dest_err_ret_trace_ptr = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::NonNull);
- ir_build_merge_err_ret_traces(irb, scope, node, coro_promise_ptr, src_err_ret_trace_ptr, dest_err_ret_trace_ptr);
- }
- Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME);
- IrInstruction *promise_result_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name, false);
- // If the type of the result handle_is_ptr then this does not actually perform a load. But we need it to,
- // because we're about to destroy the memory. So we store it into our result variable.
- IrInstruction *no_suspend_result = ir_build_load_ptr(irb, scope, node, promise_result_ptr);
- ir_build_store_ptr(irb, scope, node, my_result_var_ptr, no_suspend_result);
- ir_build_cancel(irb, scope, node, target_inst);
- ir_build_br(irb, scope, node, merge_block, const_bool_false);
-
-
- ir_set_cursor_at_end_and_append_block(irb, yes_suspend_block);
- IrInstruction *my_prev_atomic_value = ir_build_atomic_rmw(irb, scope, node,
- usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, is_suspended_mask, nullptr,
- AtomicRmwOp_or, AtomicOrderSeqCst);
- IrInstruction *my_is_suspended_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, my_prev_atomic_value, is_suspended_mask, false);
- IrInstruction *my_is_suspended_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, my_is_suspended_value, zero, false);
- ir_build_cond_br(irb, scope, node, my_is_suspended_bool, my_suspended_block, my_not_suspended_block, const_bool_false);
-
- ir_set_cursor_at_end_and_append_block(irb, my_suspended_block);
- ir_build_unreachable(irb, scope, node);
-
- ir_set_cursor_at_end_and_append_block(irb, my_not_suspended_block);
- IrInstruction *my_is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, my_prev_atomic_value, is_canceled_mask, false);
- IrInstruction *my_is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, my_is_canceled_value, zero, false);
- ir_build_cond_br(irb, scope, node, my_is_canceled_bool, cleanup_block, do_suspend_block, const_bool_false);
-
- ir_set_cursor_at_end_and_append_block(irb, do_suspend_block);
- IrInstruction *suspend_code = ir_build_coro_suspend(irb, scope, node, save_token, const_bool_false);
-
- IrInstructionSwitchBrCase *cases = allocate(2);
- cases[0].value = ir_build_const_u8(irb, scope, node, 0);
- cases[0].block = resume_block;
- cases[1].value = ir_build_const_u8(irb, scope, node, 1);
- cases[1].block = destroy_block;
- ir_build_switch_br(irb, scope, node, suspend_code, irb->exec->coro_suspend_block,
- 2, cases, const_bool_false, nullptr);
-
- ir_set_cursor_at_end_and_append_block(irb, destroy_block);
- ir_gen_cancel_target(irb, scope, node, target_inst, false, true);
- ir_mark_gen(ir_build_br(irb, scope, node, cleanup_block, const_bool_false));
-
- ir_set_cursor_at_end_and_append_block(irb, cleanup_block);
- IrInstruction *my_mask_bits = ir_build_bin_op(irb, scope, node, IrBinOpBinOr, ptr_mask, is_canceled_mask, false);
- IrInstruction *b_my_prev_atomic_value = ir_build_atomic_rmw(irb, scope, node,
- usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, my_mask_bits, nullptr,
- AtomicRmwOp_or, AtomicOrderSeqCst);
- IrInstruction *my_await_handle_addr = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, b_my_prev_atomic_value, ptr_mask, false);
- IrInstruction *dont_have_my_await_handle = ir_build_bin_op(irb, scope, node, IrBinOpCmpEq, my_await_handle_addr, zero, false);
- IrInstruction *dont_destroy_ourselves = ir_build_bin_op(irb, scope, node, IrBinOpBoolAnd, dont_have_my_await_handle, is_canceled_bool, false);
- ir_build_cond_br(irb, scope, node, dont_have_my_await_handle, do_defers_block, do_cancel_block, const_bool_false);
-
- ir_set_cursor_at_end_and_append_block(irb, do_cancel_block);
- IrInstruction *my_await_handle = ir_build_int_to_ptr(irb, scope, node, promise_type_val, my_await_handle_addr);
- ir_gen_cancel_target(irb, scope, node, my_await_handle, true, false);
- ir_mark_gen(ir_build_br(irb, scope, node, do_defers_block, const_bool_false));
-
- ir_set_cursor_at_end_and_append_block(irb, do_defers_block);
- ir_gen_defers_for_block(irb, scope, outer_scope, true);
- ir_mark_gen(ir_build_cond_br(irb, scope, node, dont_destroy_ourselves, irb->exec->coro_early_final, irb->exec->coro_final_cleanup_block, const_bool_false));
-
- ir_set_cursor_at_end_and_append_block(irb, resume_block);
- ir_build_br(irb, scope, node, merge_block, const_bool_false);
-
- ir_set_cursor_at_end_and_append_block(irb, merge_block);
- return ir_build_load_ptr(irb, scope, node, my_result_var_ptr);
+ zig_panic("TODO ir_gen_await_expr");
}
static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
assert(node->type == NodeTypeSuspend);
- ZigFn *fn_entry = exec_fn_entry(irb->exec);
- if (!fn_entry) {
- add_node_error(irb->codegen, node, buf_sprintf("suspend outside function definition"));
- return irb->codegen->invalid_instruction;
- }
- if (fn_entry->type_entry->data.fn.fn_type_id.cc != CallingConventionAsync) {
- add_node_error(irb->codegen, node, buf_sprintf("suspend in non-async function"));
- return irb->codegen->invalid_instruction;
- }
-
- ScopeDeferExpr *scope_defer_expr = get_scope_defer_expr(parent_scope);
- if (scope_defer_expr) {
- if (!scope_defer_expr->reported_err) {
- ErrorMsg *msg = add_node_error(irb->codegen, node, buf_sprintf("cannot suspend inside defer expression"));
- add_error_note(irb->codegen, msg, scope_defer_expr->base.source_node, buf_sprintf("defer here"));
- scope_defer_expr->reported_err = true;
- }
- return irb->codegen->invalid_instruction;
- }
- ScopeSuspend *existing_suspend_scope = get_scope_suspend(parent_scope);
- if (existing_suspend_scope) {
- if (!existing_suspend_scope->reported_err) {
- ErrorMsg *msg = add_node_error(irb->codegen, node, buf_sprintf("cannot suspend inside suspend block"));
- add_error_note(irb->codegen, msg, existing_suspend_scope->base.source_node, buf_sprintf("other suspend block here"));
- existing_suspend_scope->reported_err = true;
- }
- return irb->codegen->invalid_instruction;
- }
-
- Scope *outer_scope = irb->exec->begin_scope;
-
- IrBasicBlock *cleanup_block = ir_create_basic_block(irb, parent_scope, "SuspendCleanup");
- IrBasicBlock *resume_block = ir_create_basic_block(irb, parent_scope, "SuspendResume");
- IrBasicBlock *suspended_block = ir_create_basic_block(irb, parent_scope, "AlreadySuspended");
- IrBasicBlock *canceled_block = ir_create_basic_block(irb, parent_scope, "IsCanceled");
- IrBasicBlock *not_canceled_block = ir_create_basic_block(irb, parent_scope, "NotCanceled");
- IrBasicBlock *not_suspended_block = ir_create_basic_block(irb, parent_scope, "NotAlreadySuspended");
- IrBasicBlock *cancel_awaiter_block = ir_create_basic_block(irb, parent_scope, "CancelAwaiter");
-
- IrInstruction *promise_type_val = ir_build_const_type(irb, parent_scope, node, irb->codegen->builtin_types.entry_promise);
- IrInstruction *const_bool_true = ir_build_const_bool(irb, parent_scope, node, true);
- IrInstruction *const_bool_false = ir_build_const_bool(irb, parent_scope, node, false);
- IrInstruction *usize_type_val = ir_build_const_type(irb, parent_scope, node, irb->codegen->builtin_types.entry_usize);
- IrInstruction *is_canceled_mask = ir_build_const_usize(irb, parent_scope, node, 0x1); // 0b001
- IrInstruction *is_suspended_mask = ir_build_const_usize(irb, parent_scope, node, 0x2); // 0b010
- IrInstruction *zero = ir_build_const_usize(irb, parent_scope, node, 0);
- IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, parent_scope, node, 0x7); // 0b111
- IrInstruction *ptr_mask = ir_build_un_op(irb, parent_scope, node, IrUnOpBinNot, inverted_ptr_mask); // 0b111...000
-
- IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, parent_scope, node,
- usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, is_suspended_mask, nullptr,
- AtomicRmwOp_or, AtomicOrderSeqCst);
-
- IrInstruction *is_canceled_value = ir_build_bin_op(irb, parent_scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false);
- IrInstruction *is_canceled_bool = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false);
- ir_build_cond_br(irb, parent_scope, node, is_canceled_bool, canceled_block, not_canceled_block, const_bool_false);
-
- ir_set_cursor_at_end_and_append_block(irb, canceled_block);
- IrInstruction *await_handle_addr = ir_build_bin_op(irb, parent_scope, node, IrBinOpBinAnd, prev_atomic_value, ptr_mask, false);
- IrInstruction *have_await_handle = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpNotEq, await_handle_addr, zero, false);
- IrBasicBlock *post_canceled_block = irb->current_basic_block;
- ir_build_cond_br(irb, parent_scope, node, have_await_handle, cancel_awaiter_block, cleanup_block, const_bool_false);
-
- ir_set_cursor_at_end_and_append_block(irb, cancel_awaiter_block);
- IrInstruction *await_handle = ir_build_int_to_ptr(irb, parent_scope, node, promise_type_val, await_handle_addr);
- ir_gen_cancel_target(irb, parent_scope, node, await_handle, true, false);
- IrBasicBlock *post_cancel_awaiter_block = irb->current_basic_block;
- ir_build_br(irb, parent_scope, node, cleanup_block, const_bool_false);
-
- ir_set_cursor_at_end_and_append_block(irb, not_canceled_block);
- IrInstruction *is_suspended_value = ir_build_bin_op(irb, parent_scope, node, IrBinOpBinAnd, prev_atomic_value, is_suspended_mask, false);
- IrInstruction *is_suspended_bool = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpNotEq, is_suspended_value, zero, false);
- ir_build_cond_br(irb, parent_scope, node, is_suspended_bool, suspended_block, not_suspended_block, const_bool_false);
-
- ir_set_cursor_at_end_and_append_block(irb, suspended_block);
- ir_build_unreachable(irb, parent_scope, node);
-
- ir_set_cursor_at_end_and_append_block(irb, not_suspended_block);
- IrInstruction *suspend_code;
- if (node->data.suspend.block == nullptr) {
- suspend_code = ir_build_coro_suspend(irb, parent_scope, node, nullptr, const_bool_false);
- } else {
- Scope *child_scope;
- ScopeSuspend *suspend_scope = create_suspend_scope(irb->codegen, node, parent_scope);
- suspend_scope->resume_block = resume_block;
- child_scope = &suspend_scope->base;
- IrInstruction *save_token = ir_build_coro_save(irb, child_scope, node, irb->exec->coro_handle);
- ir_gen_node(irb, node->data.suspend.block, child_scope);
- suspend_code = ir_mark_gen(ir_build_coro_suspend(irb, parent_scope, node, save_token, const_bool_false));
- }
-
- IrInstructionSwitchBrCase *cases = allocate(2);
- cases[0].value = ir_mark_gen(ir_build_const_u8(irb, parent_scope, node, 0));
- cases[0].block = resume_block;
- cases[1].value = ir_mark_gen(ir_build_const_u8(irb, parent_scope, node, 1));
- cases[1].block = canceled_block;
- IrInstructionSwitchBr *switch_br = ir_build_switch_br(irb, parent_scope, node, suspend_code,
- irb->exec->coro_suspend_block, 2, cases, const_bool_false, nullptr);
- ir_mark_gen(&switch_br->base);
-
- ir_set_cursor_at_end_and_append_block(irb, cleanup_block);
- IrBasicBlock **incoming_blocks = allocate(2);
- IrInstruction **incoming_values = allocate(2);
- incoming_blocks[0] = post_canceled_block;
- incoming_values[0] = const_bool_true;
- incoming_blocks[1] = post_cancel_awaiter_block;
- incoming_values[1] = const_bool_false;
- IrInstruction *destroy_ourselves = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values,
- nullptr);
- ir_gen_defers_for_block(irb, parent_scope, outer_scope, true);
- ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, destroy_ourselves, irb->exec->coro_final_cleanup_block, irb->exec->coro_early_final, const_bool_false));
-
- ir_set_cursor_at_end_and_append_block(irb, resume_block);
- return ir_mark_gen(ir_build_const_void(irb, parent_scope, node));
+ zig_panic("TODO ir_gen_suspend");
}
static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope,
@@ -8512,8 +7747,6 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
return ir_lval_wrap(irb, scope, ir_gen_array_type(irb, scope, node), lval, result_loc);
case NodeTypePointerType:
return ir_lval_wrap(irb, scope, ir_gen_pointer_type(irb, scope, node), lval, result_loc);
- case NodeTypePromiseType:
- return ir_lval_wrap(irb, scope, ir_gen_promise_type(irb, scope, node), lval, result_loc);
case NodeTypeStringLiteral:
return ir_lval_wrap(irb, scope, ir_gen_string_literal(irb, scope, node), lval, result_loc);
case NodeTypeUndefinedLiteral:
@@ -8624,105 +7857,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
ZigFn *fn_entry = exec_fn_entry(irb->exec);
bool is_async = fn_entry != nullptr && fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync;
- IrInstruction *coro_id;
- IrInstruction *u8_ptr_type;
- IrInstruction *const_bool_false;
- IrInstruction *coro_promise_ptr;
- IrInstruction *err_ret_trace_ptr;
- ZigType *return_type;
- Buf *result_ptr_field_name;
- ZigVar *coro_size_var;
if (is_async) {
- // create the coro promise
- Scope *coro_scope = create_coro_prelude_scope(irb->codegen, node, scope);
- const_bool_false = ir_build_const_bool(irb, coro_scope, node, false);
- ZigVar *promise_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false);
-
- return_type = fn_entry->type_entry->data.fn.fn_type_id.return_type;
- IrInstruction *undef = ir_build_const_undefined(irb, coro_scope, node);
- // TODO mark this var decl as "no safety" e.g. disable initializing the undef value to 0xaa
- ZigType *coro_frame_type = get_promise_frame_type(irb->codegen, return_type);
- IrInstruction *coro_frame_type_value = ir_build_const_type(irb, coro_scope, node, coro_frame_type);
- IrInstruction *undef_coro_frame = ir_build_implicit_cast(irb, coro_scope, node, coro_frame_type_value, undef, nullptr);
- build_decl_var_and_init(irb, coro_scope, node, promise_var, undef_coro_frame, "promise", const_bool_false);
- coro_promise_ptr = ir_build_var_ptr(irb, coro_scope, node, promise_var);
-
- ZigVar *await_handle_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false);
- IrInstruction *null_value = ir_build_const_null(irb, coro_scope, node);
- IrInstruction *await_handle_type_val = ir_build_const_type(irb, coro_scope, node,
- get_optional_type(irb->codegen, irb->codegen->builtin_types.entry_promise));
- IrInstruction *null_await_handle = ir_build_implicit_cast(irb, coro_scope, node, await_handle_type_val, null_value, nullptr);
- build_decl_var_and_init(irb, coro_scope, node, await_handle_var, null_await_handle, "await_handle", const_bool_false);
- irb->exec->await_handle_var_ptr = ir_build_var_ptr(irb, coro_scope, node, await_handle_var);
-
- u8_ptr_type = ir_build_const_type(irb, coro_scope, node,
- get_pointer_to_type(irb->codegen, irb->codegen->builtin_types.entry_u8, false));
- IrInstruction *promise_as_u8_ptr = ir_build_ptr_cast_src(irb, coro_scope, node, u8_ptr_type,
- coro_promise_ptr, false);
- coro_id = ir_build_coro_id(irb, coro_scope, node, promise_as_u8_ptr);
- coro_size_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false);
- IrInstruction *coro_size = ir_build_coro_size(irb, coro_scope, node);
- build_decl_var_and_init(irb, coro_scope, node, coro_size_var, coro_size, "coro_size", const_bool_false);
- IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, coro_scope, node,
- ImplicitAllocatorIdArg);
- irb->exec->coro_allocator_var = ir_create_var(irb, node, coro_scope, nullptr, true, true, true, const_bool_false);
- build_decl_var_and_init(irb, coro_scope, node, irb->exec->coro_allocator_var, implicit_allocator_ptr,
- "allocator", const_bool_false);
- Buf *realloc_field_name = buf_create_from_str(ASYNC_REALLOC_FIELD_NAME);
- IrInstruction *realloc_fn_ptr = ir_build_field_ptr(irb, coro_scope, node, implicit_allocator_ptr, realloc_field_name, false);
- IrInstruction *realloc_fn = ir_build_load_ptr(irb, coro_scope, node, realloc_fn_ptr);
- IrInstruction *maybe_coro_mem_ptr = ir_build_coro_alloc_helper(irb, coro_scope, node, realloc_fn, coro_size);
- IrInstruction *alloc_result_is_ok = ir_build_test_nonnull(irb, coro_scope, node, maybe_coro_mem_ptr);
- IrBasicBlock *alloc_err_block = ir_create_basic_block(irb, coro_scope, "AllocError");
- IrBasicBlock *alloc_ok_block = ir_create_basic_block(irb, coro_scope, "AllocOk");
- ir_build_cond_br(irb, coro_scope, node, alloc_result_is_ok, alloc_ok_block, alloc_err_block, const_bool_false);
-
- ir_set_cursor_at_end_and_append_block(irb, alloc_err_block);
- // we can return undefined here, because the caller passes a pointer to the error struct field
- // in the error union result, and we populate it in case of allocation failure.
- ir_build_return(irb, coro_scope, node, undef);
-
- ir_set_cursor_at_end_and_append_block(irb, alloc_ok_block);
- IrInstruction *coro_mem_ptr = ir_build_ptr_cast_src(irb, coro_scope, node, u8_ptr_type, maybe_coro_mem_ptr,
- false);
- irb->exec->coro_handle = ir_build_coro_begin(irb, coro_scope, node, coro_id, coro_mem_ptr);
-
- Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME);
- irb->exec->atomic_state_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,
- atomic_state_field_name, false);
- IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0);
- ir_build_store_ptr(irb, scope, node, irb->exec->atomic_state_field_ptr, zero);
- Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME);
- irb->exec->coro_result_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name, false);
- result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME);
- irb->exec->coro_result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name, false);
- ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr, irb->exec->coro_result_field_ptr);
- if (irb->codegen->have_err_ret_tracing) {
- // initialize the error return trace
- Buf *return_addresses_field_name = buf_create_from_str(RETURN_ADDRESSES_FIELD_NAME);
- IrInstruction *return_addresses_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, return_addresses_field_name, false);
-
- Buf *err_ret_trace_field_name = buf_create_from_str(ERR_RET_TRACE_FIELD_NAME);
- err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name, false);
- ir_build_mark_err_ret_trace_ptr(irb, scope, node, err_ret_trace_ptr);
-
- // coordinate with builtin.zig
- Buf *index_name = buf_create_from_str("index");
- IrInstruction *index_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, index_name, false);
- ir_build_store_ptr(irb, scope, node, index_ptr, zero);
-
- Buf *instruction_addresses_name = buf_create_from_str("instruction_addresses");
- IrInstruction *addrs_slice_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, instruction_addresses_name, false);
-
- IrInstruction *slice_value = ir_build_slice_src(irb, scope, node, return_addresses_ptr, zero, nullptr, false, no_result_loc());
- ir_build_store_ptr(irb, scope, node, addrs_slice_ptr, slice_value);
- }
-
-
- irb->exec->coro_early_final = ir_create_basic_block(irb, scope, "CoroEarlyFinal");
- irb->exec->coro_normal_final = ir_create_basic_block(irb, scope, "CoroNormalFinal");
- irb->exec->coro_suspend_block = ir_create_basic_block(irb, scope, "Suspend");
- irb->exec->coro_final_cleanup_block = ir_create_basic_block(irb, scope, "FinalCleanup");
+ zig_panic("ir_gen async fn");
}
IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone, nullptr);
@@ -8735,117 +7871,6 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
ir_gen_async_return(irb, scope, result->source_node, result, true);
}
- if (is_async) {
- IrBasicBlock *invalid_resume_block = ir_create_basic_block(irb, scope, "InvalidResume");
- IrBasicBlock *check_free_block = ir_create_basic_block(irb, scope, "CheckFree");
-
- ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_early_final);
- IrInstruction *const_bool_true = ir_build_const_bool(irb, scope, node, true);
- IrInstruction *suspend_code = ir_build_coro_suspend(irb, scope, node, nullptr, const_bool_true);
- IrInstructionSwitchBrCase *cases = allocate(2);
- cases[0].value = ir_build_const_u8(irb, scope, node, 0);
- cases[0].block = invalid_resume_block;
- cases[1].value = ir_build_const_u8(irb, scope, node, 1);
- cases[1].block = irb->exec->coro_final_cleanup_block;
- ir_build_switch_br(irb, scope, node, suspend_code, irb->exec->coro_suspend_block, 2, cases, const_bool_false, nullptr);
-
- ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_suspend_block);
- ir_build_coro_end(irb, scope, node);
- ir_build_return(irb, scope, node, irb->exec->coro_handle);
-
- ir_set_cursor_at_end_and_append_block(irb, invalid_resume_block);
- ir_build_unreachable(irb, scope, node);
-
- ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_normal_final);
- if (type_has_bits(return_type)) {
- IrInstruction *u8_ptr_type_unknown_len = ir_build_const_type(irb, scope, node,
- get_pointer_to_type_extra(irb->codegen, irb->codegen->builtin_types.entry_u8,
- false, false, PtrLenUnknown, 0, 0, 0, false));
- IrInstruction *result_ptr = ir_build_load_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr);
- IrInstruction *result_ptr_as_u8_ptr = ir_build_ptr_cast_src(irb, scope, node, u8_ptr_type_unknown_len,
- result_ptr, false);
- IrInstruction *return_value_ptr_as_u8_ptr = ir_build_ptr_cast_src(irb, scope, node,
- u8_ptr_type_unknown_len, irb->exec->coro_result_field_ptr, false);
- IrInstruction *return_type_inst = ir_build_const_type(irb, scope, node,
- fn_entry->type_entry->data.fn.fn_type_id.return_type);
- IrInstruction *size_of_ret_val = ir_build_size_of(irb, scope, node, return_type_inst);
- ir_build_memcpy(irb, scope, node, result_ptr_as_u8_ptr, return_value_ptr_as_u8_ptr, size_of_ret_val);
- }
- if (irb->codegen->have_err_ret_tracing) {
- Buf *err_ret_trace_ptr_field_name = buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME);
- IrInstruction *err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name, false);
- IrInstruction *dest_err_ret_trace_ptr = ir_build_load_ptr(irb, scope, node, err_ret_trace_ptr_field_ptr);
- ir_build_merge_err_ret_traces(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr, dest_err_ret_trace_ptr);
- }
- // Before we destroy the coroutine frame, we need to load the target promise into
- // a register or local variable which does not get spilled into the frame,
- // otherwise llvm tries to access memory inside the destroyed frame.
- IrInstruction *unwrapped_await_handle_ptr = ir_build_optional_unwrap_ptr(irb, scope, node,
- irb->exec->await_handle_var_ptr, false, false);
- IrInstruction *await_handle_in_block = ir_build_load_ptr(irb, scope, node, unwrapped_await_handle_ptr);
- ir_build_br(irb, scope, node, check_free_block, const_bool_false);
-
- ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_final_cleanup_block);
- ir_build_br(irb, scope, node, check_free_block, const_bool_false);
-
- ir_set_cursor_at_end_and_append_block(irb, check_free_block);
- IrBasicBlock **incoming_blocks = allocate(2);
- IrInstruction **incoming_values = allocate(2);
- incoming_blocks[0] = irb->exec->coro_final_cleanup_block;
- incoming_values[0] = const_bool_false;
- incoming_blocks[1] = irb->exec->coro_normal_final;
- incoming_values[1] = const_bool_true;
- IrInstruction *resume_awaiter = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr);
-
- IrBasicBlock **merge_incoming_blocks = allocate(2);
- IrInstruction **merge_incoming_values = allocate(2);
- merge_incoming_blocks[0] = irb->exec->coro_final_cleanup_block;
- merge_incoming_values[0] = ir_build_const_undefined(irb, scope, node);
- merge_incoming_blocks[1] = irb->exec->coro_normal_final;
- merge_incoming_values[1] = await_handle_in_block;
- IrInstruction *awaiter_handle = ir_build_phi(irb, scope, node, 2, merge_incoming_blocks, merge_incoming_values, nullptr);
-
- Buf *shrink_field_name = buf_create_from_str(ASYNC_SHRINK_FIELD_NAME);
- IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, scope, node,
- ImplicitAllocatorIdLocalVar);
- IrInstruction *shrink_fn_ptr = ir_build_field_ptr(irb, scope, node, implicit_allocator_ptr, shrink_field_name, false);
- IrInstruction *shrink_fn = ir_build_load_ptr(irb, scope, node, shrink_fn_ptr);
- IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0);
- IrInstruction *coro_mem_ptr_maybe = ir_build_coro_free(irb, scope, node, coro_id, irb->exec->coro_handle);
- IrInstruction *u8_ptr_type_unknown_len = ir_build_const_type(irb, scope, node,
- get_pointer_to_type_extra(irb->codegen, irb->codegen->builtin_types.entry_u8,
- false, false, PtrLenUnknown, 0, 0, 0, false));
- IrInstruction *coro_mem_ptr = ir_build_ptr_cast_src(irb, scope, node, u8_ptr_type_unknown_len,
- coro_mem_ptr_maybe, false);
- IrInstruction *coro_mem_ptr_ref = ir_build_ref(irb, scope, node, coro_mem_ptr, true, false);
- IrInstruction *coro_size_ptr = ir_build_var_ptr(irb, scope, node, coro_size_var);
- IrInstruction *coro_size = ir_build_load_ptr(irb, scope, node, coro_size_ptr);
- IrInstruction *mem_slice = ir_build_slice_src(irb, scope, node, coro_mem_ptr_ref, zero, coro_size, false,
- no_result_loc());
- size_t arg_count = 5;
- IrInstruction **args = allocate(arg_count);
- args[0] = implicit_allocator_ptr; // self
- args[1] = mem_slice; // old_mem
- args[2] = ir_build_const_usize(irb, scope, node, 8); // old_align
- // TODO: intentional memory leak here. If this is set to 0 then there is an issue where a coroutine
- // calls the function and it frees its own stack frame, but then the return value is a slice, which
- // is implemented as an sret struct. writing to the return pointer causes invalid memory write.
- // We could work around it by having a global helper function which has a void return type
- // and calling that instead. But instead this hack will suffice until I rework coroutines to be
- // non-allocating. Basically coroutines are not supported right now until they are reworked.
- args[3] = ir_build_const_usize(irb, scope, node, 1); // new_size
- args[4] = ir_build_const_usize(irb, scope, node, 1); // new_align
- ir_build_call_src(irb, scope, node, nullptr, shrink_fn, arg_count, args, false, FnInlineAuto, false, nullptr,
- nullptr, no_result_loc());
-
- IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume");
- ir_build_cond_br(irb, scope, node, resume_awaiter, resume_block, irb->exec->coro_suspend_block, const_bool_false);
-
- ir_set_cursor_at_end_and_append_block(irb, resume_block);
- ir_gen_resume_target(irb, scope, node, awaiter_handle);
- ir_build_br(irb, scope, node, irb->exec->coro_suspend_block, const_bool_false);
- }
-
return true;
}
@@ -10189,12 +9214,6 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
return result;
}
- if (wanted_type == ira->codegen->builtin_types.entry_promise &&
- actual_type->id == ZigTypeIdPromise)
- {
- return result;
- }
-
// fn
if (wanted_type->id == ZigTypeIdFn &&
actual_type->id == ZigTypeIdFn)
@@ -10229,20 +9248,6 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
return result;
}
}
- if (!wanted_type->data.fn.is_generic && wanted_type->data.fn.fn_type_id.cc == CallingConventionAsync) {
- ConstCastOnly child = types_match_const_cast_only(ira,
- actual_type->data.fn.fn_type_id.async_allocator_type,
- wanted_type->data.fn.fn_type_id.async_allocator_type,
- source_node, false);
- if (child.id == ConstCastResultIdInvalid)
- return child;
- if (child.id != ConstCastResultIdOk) {
- result.id = ConstCastResultIdAsyncAllocatorType;
- result.data.async_allocator_type = allocate_nonzero(1);
- *result.data.async_allocator_type = child;
- return result;
- }
- }
if (wanted_type->data.fn.fn_type_id.param_count != actual_type->data.fn.fn_type_id.param_count) {
result.id = ConstCastResultIdFnArgCount;
return result;
@@ -12559,12 +11564,10 @@ static IrInstruction *ir_analyze_int_to_c_ptr(IrAnalyze *ira, IrInstruction *sou
static bool is_pointery_and_elem_is_not_pointery(ZigType *ty) {
if (ty->id == ZigTypeIdPointer) return ty->data.pointer.child_type->id != ZigTypeIdPointer;
if (ty->id == ZigTypeIdFn) return true;
- if (ty->id == ZigTypeIdPromise) return true;
if (ty->id == ZigTypeIdOptional) {
ZigType *ptr_ty = ty->data.maybe.child_type;
if (ptr_ty->id == ZigTypeIdPointer) return ptr_ty->data.pointer.child_type->id != ZigTypeIdPointer;
if (ptr_ty->id == ZigTypeIdFn) return true;
- if (ptr_ty->id == ZigTypeIdPromise) return true;
}
return false;
}
@@ -13640,7 +12643,6 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *
case ZigTypeIdOpaque:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
- case ZigTypeIdPromise:
case ZigTypeIdEnum:
case ZigTypeIdEnumLiteral:
operator_allowed = is_equality_cmp;
@@ -15021,7 +14023,6 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdOpaque:
- case ZigTypeIdPromise:
ir_add_error(ira, target,
buf_sprintf("invalid export target '%s'", buf_ptr(&type_value->name)));
break;
@@ -15045,7 +14046,6 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdOpaque:
- case ZigTypeIdPromise:
case ZigTypeIdEnumLiteral:
ir_add_error(ira, target,
buf_sprintf("invalid export target type '%s'", buf_ptr(&target->value.type->name)));
@@ -15124,42 +14124,6 @@ static IrInstruction *ir_analyze_instruction_error_union(IrAnalyze *ira,
return ir_const_type(ira, &instruction->base, result_type);
}
-IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_instr, ImplicitAllocatorId id) {
- ZigFn *parent_fn_entry = exec_fn_entry(ira->new_irb.exec);
- if (parent_fn_entry == nullptr) {
- ir_add_error(ira, source_instr, buf_sprintf("no implicit allocator available"));
- return ira->codegen->invalid_instruction;
- }
-
- FnTypeId *parent_fn_type = &parent_fn_entry->type_entry->data.fn.fn_type_id;
- if (parent_fn_type->cc != CallingConventionAsync) {
- ir_add_error(ira, source_instr, buf_sprintf("async function call from non-async caller requires allocator parameter"));
- return ira->codegen->invalid_instruction;
- }
-
- assert(parent_fn_type->async_allocator_type != nullptr);
-
- switch (id) {
- case ImplicitAllocatorIdArg:
- {
- IrInstruction *result = ir_build_get_implicit_allocator(&ira->new_irb, source_instr->scope,
- source_instr->source_node, ImplicitAllocatorIdArg);
- result->value.type = parent_fn_type->async_allocator_type;
- return result;
- }
- case ImplicitAllocatorIdLocalVar:
- {
- ZigVar *coro_allocator_var = ira->old_irb.exec->coro_allocator_var;
- assert(coro_allocator_var != nullptr);
- IrInstruction *var_ptr_inst = ir_get_var_ptr(ira, source_instr, coro_allocator_var);
- IrInstruction *result = ir_get_deref(ira, source_instr, var_ptr_inst, nullptr);
- assert(result->value.type != nullptr);
- return result;
- }
- }
- zig_unreachable();
-}
-
static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_inst, ZigType *var_type,
uint32_t align, const char *name_hint, bool force_comptime)
{
@@ -15589,50 +14553,6 @@ static IrInstruction *ir_analyze_instruction_reset_result(IrAnalyze *ira, IrInst
return ir_const_void(ira, &instruction->base);
}
-static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, ZigFn *fn_entry,
- ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count,
- IrInstruction *async_allocator_inst)
-{
- Buf *realloc_field_name = buf_create_from_str(ASYNC_REALLOC_FIELD_NAME);
- ir_assert(async_allocator_inst->value.type->id == ZigTypeIdPointer, &call_instruction->base);
- ZigType *container_type = async_allocator_inst->value.type->data.pointer.child_type;
- IrInstruction *field_ptr_inst = ir_analyze_container_field_ptr(ira, realloc_field_name, &call_instruction->base,
- async_allocator_inst, container_type, false);
- if (type_is_invalid(field_ptr_inst->value.type)) {
- return ira->codegen->invalid_instruction;
- }
- ZigType *ptr_to_realloc_fn_type = field_ptr_inst->value.type;
- ir_assert(ptr_to_realloc_fn_type->id == ZigTypeIdPointer, &call_instruction->base);
-
- ZigType *realloc_fn_type = ptr_to_realloc_fn_type->data.pointer.child_type;
- if (realloc_fn_type->id != ZigTypeIdFn) {
- ir_add_error(ira, &call_instruction->base,
- buf_sprintf("expected reallocation function, found '%s'", buf_ptr(&realloc_fn_type->name)));
- return ira->codegen->invalid_instruction;
- }
-
- ZigType *realloc_fn_return_type = realloc_fn_type->data.fn.fn_type_id.return_type;
- if (realloc_fn_return_type->id != ZigTypeIdErrorUnion) {
- ir_add_error(ira, fn_ref,
- buf_sprintf("expected allocation function to return error union, but it returns '%s'", buf_ptr(&realloc_fn_return_type->name)));
- return ira->codegen->invalid_instruction;
- }
- ZigType *alloc_fn_error_set_type = realloc_fn_return_type->data.error_union.err_set_type;
- ZigType *return_type = fn_type->data.fn.fn_type_id.return_type;
- ZigType *promise_type = get_promise_type(ira->codegen, return_type);
- ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type);
-
- IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, no_result_loc(),
- async_return_type, nullptr, true, true);
- if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {
- return result_loc;
- }
-
- return ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, arg_count,
- casted_args, FnInlineAuto, true, async_allocator_inst, nullptr, result_loc,
- async_return_type);
-}
-
static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node,
IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i)
{
@@ -16330,32 +15250,8 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
break;
}
}
- IrInstruction *async_allocator_inst = nullptr;
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 = 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;
- }
- IrInstruction *uncasted_async_allocator_inst;
- if (call_instruction->async_allocator == nullptr) {
- uncasted_async_allocator_inst = ir_get_implicit_allocator(ira, &call_instruction->base,
- ImplicitAllocatorIdLocalVar);
- if (type_is_invalid(uncasted_async_allocator_inst->value.type))
- return ira->codegen->invalid_instruction;
- } else {
- uncasted_async_allocator_inst = call_instruction->async_allocator->child;
- if (type_is_invalid(uncasted_async_allocator_inst->value.type))
- return ira->codegen->invalid_instruction;
- }
- if (inst_fn_type_id.async_allocator_type == nullptr) {
- inst_fn_type_id.async_allocator_type = uncasted_async_allocator_inst->value.type;
- }
- async_allocator_inst = ir_implicit_cast(ira, uncasted_async_allocator_inst, inst_fn_type_id.async_allocator_type);
- if (type_is_invalid(async_allocator_inst->value.type))
- return ira->codegen->invalid_instruction;
+ zig_panic("TODO async call");
}
auto existing_entry = ira->codegen->generic_table.put_unique(generic_id, impl_fn);
@@ -16398,15 +15294,12 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
size_t impl_param_count = impl_fn_type_id->param_count;
if (call_instruction->is_async) {
- IrInstruction *result = ir_analyze_async_call(ira, call_instruction, impl_fn, impl_fn->type_entry,
- fn_ref, casted_args, impl_param_count, async_allocator_inst);
- return ir_finish_anal(ira, result);
+ zig_panic("TODO async call");
}
- assert(async_allocator_inst == nullptr);
IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base,
impl_fn, nullptr, impl_param_count, casted_args, fn_inline,
- call_instruction->is_async, nullptr, casted_new_stack, result_loc,
+ call_instruction->is_async, casted_new_stack, result_loc,
impl_fn_type_id->return_type);
return ir_finish_anal(ira, new_call_instruction);
@@ -16474,25 +15367,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
return ira->codegen->invalid_instruction;
if (call_instruction->is_async) {
- IrInstruction *uncasted_async_allocator_inst;
- if (call_instruction->async_allocator == nullptr) {
- uncasted_async_allocator_inst = ir_get_implicit_allocator(ira, &call_instruction->base,
- ImplicitAllocatorIdLocalVar);
- if (type_is_invalid(uncasted_async_allocator_inst->value.type))
- return ira->codegen->invalid_instruction;
- } else {
- uncasted_async_allocator_inst = call_instruction->async_allocator->child;
- if (type_is_invalid(uncasted_async_allocator_inst->value.type))
- return ira->codegen->invalid_instruction;
-
- }
- IrInstruction *async_allocator_inst = ir_implicit_cast(ira, uncasted_async_allocator_inst, fn_type_id->async_allocator_type);
- if (type_is_invalid(async_allocator_inst->value.type))
- return ira->codegen->invalid_instruction;
-
- IrInstruction *result = ir_analyze_async_call(ira, call_instruction, fn_entry, fn_type, fn_ref,
- casted_args, call_param_count, async_allocator_inst);
- return ir_finish_anal(ira, result);
+ zig_panic("TODO async call");
}
if (fn_entry != nullptr && fn_entry->fn_inline == FnInlineAlways && fn_inline == FnInlineNever) {
@@ -16513,7 +15388,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
}
IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref,
- call_param_count, casted_args, fn_inline, false, nullptr, casted_new_stack,
+ call_param_count, casted_args, fn_inline, false, casted_new_stack,
result_loc, return_type);
return ir_finish_anal(ira, new_call_instruction);
}
@@ -16694,7 +15569,6 @@ static IrInstruction *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op_
case ZigTypeIdFn:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
- case ZigTypeIdPromise:
return ir_const_type(ira, &un_op_instruction->base, get_optional_type(ira->codegen, type_entry));
case ZigTypeIdUnreachable:
case ZigTypeIdOpaque:
@@ -18465,7 +17339,6 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira,
case ZigTypeIdUnion:
case ZigTypeIdFn:
case ZigTypeIdBoundFn:
- case ZigTypeIdPromise:
case ZigTypeIdVector:
{
ResolveStatus needed_status = (align_bytes == 0) ?
@@ -18580,7 +17453,6 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira,
case ZigTypeIdUnion:
case ZigTypeIdFn:
case ZigTypeIdBoundFn:
- case ZigTypeIdPromise:
case ZigTypeIdVector:
{
if ((err = ensure_complete_type(ira->codegen, child_type)))
@@ -18592,22 +17464,6 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira,
zig_unreachable();
}
-static IrInstruction *ir_analyze_instruction_promise_type(IrAnalyze *ira, IrInstructionPromiseType *instruction) {
- ZigType *promise_type;
-
- if (instruction->payload_type == nullptr) {
- promise_type = ira->codegen->builtin_types.entry_promise;
- } else {
- ZigType *payload_type = ir_resolve_type(ira, instruction->payload_type->child);
- if (type_is_invalid(payload_type))
- return ira->codegen->invalid_instruction;
-
- promise_type = get_promise_type(ira->codegen, payload_type);
- }
-
- return ir_const_type(ira, &instruction->base, promise_type);
-}
-
static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira,
IrInstructionSizeOf *size_of_instruction)
{
@@ -18647,7 +17503,6 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira,
case ZigTypeIdEnum:
case ZigTypeIdUnion:
case ZigTypeIdFn:
- case ZigTypeIdPromise:
case ZigTypeIdVector:
{
uint64_t size_in_bytes = type_size(ira->codegen, type_entry);
@@ -19134,7 +17989,6 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,
case ZigTypeIdComptimeInt:
case ZigTypeIdEnumLiteral:
case ZigTypeIdPointer:
- case ZigTypeIdPromise:
case ZigTypeIdFn:
case ZigTypeIdErrorSet: {
if (pointee_val) {
@@ -20645,32 +19499,6 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
fields[0].type = ira->codegen->builtin_types.entry_type;
fields[0].data.x_type = type_entry->data.maybe.child_type;
- break;
- }
- case ZigTypeIdPromise:
- {
- result = create_const_vals(1);
- result->special = ConstValSpecialStatic;
- result->type = ir_type_info_get_type(ira, "Promise", nullptr);
-
- ConstExprValue *fields = create_const_vals(1);
- result->data.x_struct.fields = fields;
-
- // child: ?type
- ensure_field_index(result->type, "child", 0);
- fields[0].special = ConstValSpecialStatic;
- fields[0].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type);
-
- if (type_entry->data.promise.result_type == nullptr)
- fields[0].data.x_optional = nullptr;
- else {
- ConstExprValue *child_type = create_const_vals(1);
- child_type->special = ConstValSpecialStatic;
- child_type->type = ira->codegen->builtin_types.entry_type;
- child_type->data.x_type = type_entry->data.promise.result_type;
- fields[0].data.x_optional = child_type;
- }
-
break;
}
case ZigTypeIdEnum:
@@ -20982,7 +19810,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
result->special = ConstValSpecialStatic;
result->type = ir_type_info_get_type(ira, "Fn", nullptr);
- ConstExprValue *fields = create_const_vals(6);
+ ConstExprValue *fields = create_const_vals(5);
result->data.x_struct.fields = fields;
// calling_convention: TypeInfo.CallingConvention
@@ -21015,19 +19843,6 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
return_type->data.x_type = type_entry->data.fn.fn_type_id.return_type;
fields[3].data.x_optional = return_type;
}
- // async_allocator_type: type
- ensure_field_index(result->type, "async_allocator_type", 4);
- fields[4].special = ConstValSpecialStatic;
- fields[4].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type);
- if (type_entry->data.fn.fn_type_id.async_allocator_type == nullptr)
- fields[4].data.x_optional = nullptr;
- else {
- ConstExprValue *async_alloc_type = create_const_vals(1);
- async_alloc_type->special = ConstValSpecialStatic;
- async_alloc_type->type = ira->codegen->builtin_types.entry_type;
- async_alloc_type->data.x_type = type_entry->data.fn.fn_type_id.async_allocator_type;
- fields[4].data.x_optional = async_alloc_type;
- }
// args: []TypeInfo.FnArg
ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg", nullptr);
if ((err = type_resolve(ira->codegen, type_info_fn_arg_type, ResolveStatusSizeKnown))) {
@@ -21042,10 +19857,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
fn_arg_array->data.x_array.special = ConstArraySpecialNone;
fn_arg_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count);
- init_const_slice(ira->codegen, &fields[5], fn_arg_array, 0, fn_arg_count, false);
+ init_const_slice(ira->codegen, &fields[4], fn_arg_array, 0, fn_arg_count, false);
- for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++)
- {
+ for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) {
FnTypeParamInfo *fn_param_info = &type_entry->data.fn.fn_type_id.param_info[fn_arg_index];
ConstExprValue *fn_arg_val = &fn_arg_array->data.x_array.data.s_none.elements[fn_arg_index];
@@ -22803,11 +21617,7 @@ static IrInstruction *ir_analyze_instruction_frame_address(IrAnalyze *ira, IrIns
}
static IrInstruction *ir_analyze_instruction_handle(IrAnalyze *ira, IrInstructionHandle *instruction) {
- IrInstruction *result = ir_build_handle(&ira->new_irb, instruction->base.scope, instruction->base.source_node);
- ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
- assert(fn_entry != nullptr);
- result->value.type = get_promise_type(ira->codegen, fn_entry->type_entry->data.fn.fn_type_id.return_type);
- return result;
+ zig_panic("TODO anlayze @handle()");
}
static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstructionAlignOf *instruction) {
@@ -22841,7 +21651,6 @@ static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruct
case ZigTypeIdInt:
case ZigTypeIdFloat:
case ZigTypeIdPointer:
- case ZigTypeIdPromise:
case ZigTypeIdArray:
case ZigTypeIdStruct:
case ZigTypeIdOptional:
@@ -23401,15 +22210,7 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct
}
if (fn_type_id.cc == CallingConventionAsync) {
- if (instruction->async_allocator_type_value == nullptr) {
- ir_add_error(ira, &instruction->base,
- buf_sprintf("async fn proto missing allocator type"));
- return ira->codegen->invalid_instruction;
- }
- IrInstruction *async_allocator_type_value = instruction->async_allocator_type_value->child;
- fn_type_id.async_allocator_type = ir_resolve_type(ira, async_allocator_type_value);
- if (type_is_invalid(fn_type_id.async_allocator_type))
- return ira->codegen->invalid_instruction;
+ zig_panic("TODO");
}
return ir_const_type(ira, &instruction->base, get_fn_type(ira->codegen, &fn_type_id));
@@ -23905,7 +22706,6 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
case ZigTypeIdEnumLiteral:
case ZigTypeIdUndefined:
case ZigTypeIdNull:
- case ZigTypeIdPromise:
case ZigTypeIdErrorUnion:
case ZigTypeIdErrorSet:
zig_unreachable();
@@ -24059,7 +22859,6 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
case ZigTypeIdEnumLiteral:
case ZigTypeIdUndefined:
case ZigTypeIdNull:
- case ZigTypeIdPromise:
zig_unreachable();
case ZigTypeIdVoid:
return ErrorNone;
@@ -24546,181 +23345,7 @@ static IrInstruction *ir_analyze_instruction_tag_type(IrAnalyze *ira, IrInstruct
}
static IrInstruction *ir_analyze_instruction_cancel(IrAnalyze *ira, IrInstructionCancel *instruction) {
- IrInstruction *target_inst = instruction->target->child;
- if (type_is_invalid(target_inst->value.type))
- return ira->codegen->invalid_instruction;
- IrInstruction *casted_target = ir_implicit_cast(ira, target_inst, ira->codegen->builtin_types.entry_promise);
- if (type_is_invalid(casted_target->value.type))
- return ira->codegen->invalid_instruction;
-
- IrInstruction *result = ir_build_cancel(&ira->new_irb, instruction->base.scope, instruction->base.source_node, casted_target);
- result->value.type = ira->codegen->builtin_types.entry_void;
- result->value.special = ConstValSpecialStatic;
- return result;
-}
-
-static IrInstruction *ir_analyze_instruction_coro_id(IrAnalyze *ira, IrInstructionCoroId *instruction) {
- IrInstruction *promise_ptr = instruction->promise_ptr->child;
- if (type_is_invalid(promise_ptr->value.type))
- return ira->codegen->invalid_instruction;
-
- IrInstruction *result = ir_build_coro_id(&ira->new_irb, instruction->base.scope, instruction->base.source_node,
- promise_ptr);
- result->value.type = ira->codegen->builtin_types.entry_usize;
- return result;
-}
-
-static IrInstruction *ir_analyze_instruction_coro_alloc(IrAnalyze *ira, IrInstructionCoroAlloc *instruction) {
- IrInstruction *coro_id = instruction->coro_id->child;
- if (type_is_invalid(coro_id->value.type))
- return ira->codegen->invalid_instruction;
-
- IrInstruction *result = ir_build_coro_alloc(&ira->new_irb, instruction->base.scope, instruction->base.source_node,
- coro_id);
- result->value.type = ira->codegen->builtin_types.entry_bool;
- return result;
-}
-
-static IrInstruction *ir_analyze_instruction_coro_size(IrAnalyze *ira, IrInstructionCoroSize *instruction) {
- IrInstruction *result = ir_build_coro_size(&ira->new_irb, instruction->base.scope, instruction->base.source_node);
- result->value.type = ira->codegen->builtin_types.entry_usize;
- return result;
-}
-
-static IrInstruction *ir_analyze_instruction_coro_begin(IrAnalyze *ira, IrInstructionCoroBegin *instruction) {
- IrInstruction *coro_id = instruction->coro_id->child;
- if (type_is_invalid(coro_id->value.type))
- return ira->codegen->invalid_instruction;
-
- IrInstruction *coro_mem_ptr = instruction->coro_mem_ptr->child;
- if (type_is_invalid(coro_mem_ptr->value.type))
- return ira->codegen->invalid_instruction;
-
- ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
- ir_assert(fn_entry != nullptr, &instruction->base);
- IrInstruction *result = ir_build_coro_begin(&ira->new_irb, instruction->base.scope, instruction->base.source_node,
- coro_id, coro_mem_ptr);
- result->value.type = get_promise_type(ira->codegen, fn_entry->type_entry->data.fn.fn_type_id.return_type);
- return result;
-}
-
-static IrInstruction *ir_analyze_instruction_get_implicit_allocator(IrAnalyze *ira, IrInstructionGetImplicitAllocator *instruction) {
- return ir_get_implicit_allocator(ira, &instruction->base, instruction->id);
-}
-
-static IrInstruction *ir_analyze_instruction_coro_alloc_fail(IrAnalyze *ira, IrInstructionCoroAllocFail *instruction) {
- IrInstruction *err_val = instruction->err_val->child;
- if (type_is_invalid(err_val->value.type))
- return ir_unreach_error(ira);
-
- IrInstruction *result = ir_build_coro_alloc_fail(&ira->new_irb, instruction->base.scope, instruction->base.source_node, err_val);
- result->value.type = ira->codegen->builtin_types.entry_unreachable;
- return ir_finish_anal(ira, result);
-}
-
-static IrInstruction *ir_analyze_instruction_coro_suspend(IrAnalyze *ira, IrInstructionCoroSuspend *instruction) {
- IrInstruction *save_point = nullptr;
- if (instruction->save_point != nullptr) {
- save_point = instruction->save_point->child;
- if (type_is_invalid(save_point->value.type))
- return ira->codegen->invalid_instruction;
- }
-
- IrInstruction *is_final = instruction->is_final->child;
- if (type_is_invalid(is_final->value.type))
- return ira->codegen->invalid_instruction;
-
- IrInstruction *result = ir_build_coro_suspend(&ira->new_irb, instruction->base.scope,
- instruction->base.source_node, save_point, is_final);
- result->value.type = ira->codegen->builtin_types.entry_u8;
- return result;
-}
-
-static IrInstruction *ir_analyze_instruction_coro_end(IrAnalyze *ira, IrInstructionCoroEnd *instruction) {
- IrInstruction *result = ir_build_coro_end(&ira->new_irb, instruction->base.scope,
- instruction->base.source_node);
- result->value.type = ira->codegen->builtin_types.entry_void;
- return result;
-}
-
-static IrInstruction *ir_analyze_instruction_coro_free(IrAnalyze *ira, IrInstructionCoroFree *instruction) {
- IrInstruction *coro_id = instruction->coro_id->child;
- if (type_is_invalid(coro_id->value.type))
- return ira->codegen->invalid_instruction;
-
- IrInstruction *coro_handle = instruction->coro_handle->child;
- if (type_is_invalid(coro_handle->value.type))
- return ira->codegen->invalid_instruction;
-
- IrInstruction *result = ir_build_coro_free(&ira->new_irb, instruction->base.scope,
- instruction->base.source_node, coro_id, coro_handle);
- ZigType *ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, false);
- result->value.type = get_optional_type(ira->codegen, ptr_type);
- return result;
-}
-
-static IrInstruction *ir_analyze_instruction_coro_resume(IrAnalyze *ira, IrInstructionCoroResume *instruction) {
- IrInstruction *awaiter_handle = instruction->awaiter_handle->child;
- if (type_is_invalid(awaiter_handle->value.type))
- return ira->codegen->invalid_instruction;
-
- IrInstruction *casted_target = ir_implicit_cast(ira, awaiter_handle, ira->codegen->builtin_types.entry_promise);
- if (type_is_invalid(casted_target->value.type))
- return ira->codegen->invalid_instruction;
-
- IrInstruction *result = ir_build_coro_resume(&ira->new_irb, instruction->base.scope,
- instruction->base.source_node, casted_target);
- result->value.type = ira->codegen->builtin_types.entry_void;
- return result;
-}
-
-static IrInstruction *ir_analyze_instruction_coro_save(IrAnalyze *ira, IrInstructionCoroSave *instruction) {
- IrInstruction *coro_handle = instruction->coro_handle->child;
- if (type_is_invalid(coro_handle->value.type))
- return ira->codegen->invalid_instruction;
-
- IrInstruction *result = ir_build_coro_save(&ira->new_irb, instruction->base.scope,
- instruction->base.source_node, coro_handle);
- result->value.type = ira->codegen->builtin_types.entry_usize;
- return result;
-}
-
-static IrInstruction *ir_analyze_instruction_coro_promise(IrAnalyze *ira, IrInstructionCoroPromise *instruction) {
- IrInstruction *coro_handle = instruction->coro_handle->child;
- if (type_is_invalid(coro_handle->value.type))
- return ira->codegen->invalid_instruction;
-
- if (coro_handle->value.type->id != ZigTypeIdPromise ||
- coro_handle->value.type->data.promise.result_type == nullptr)
- {
- ir_add_error(ira, &instruction->base, buf_sprintf("expected promise->T, found '%s'",
- buf_ptr(&coro_handle->value.type->name)));
- return ira->codegen->invalid_instruction;
- }
-
- ZigType *coro_frame_type = get_promise_frame_type(ira->codegen,
- coro_handle->value.type->data.promise.result_type);
-
- IrInstruction *result = ir_build_coro_promise(&ira->new_irb, instruction->base.scope,
- instruction->base.source_node, coro_handle);
- result->value.type = get_pointer_to_type(ira->codegen, coro_frame_type, false);
- return result;
-}
-
-static IrInstruction *ir_analyze_instruction_coro_alloc_helper(IrAnalyze *ira, IrInstructionCoroAllocHelper *instruction) {
- IrInstruction *realloc_fn = instruction->realloc_fn->child;
- if (type_is_invalid(realloc_fn->value.type))
- return ira->codegen->invalid_instruction;
-
- IrInstruction *coro_size = instruction->coro_size->child;
- if (type_is_invalid(coro_size->value.type))
- return ira->codegen->invalid_instruction;
-
- IrInstruction *result = ir_build_coro_alloc_helper(&ira->new_irb, instruction->base.scope,
- instruction->base.source_node, realloc_fn, coro_size);
- ZigType *u8_ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, false);
- result->value.type = get_optional_type(ira->codegen, u8_ptr_type);
- return result;
+ zig_panic("TODO analyze cancel");
}
static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op) {
@@ -24853,65 +23478,6 @@ static IrInstruction *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstr
return result;
}
-static IrInstruction *ir_analyze_instruction_promise_result_type(IrAnalyze *ira, IrInstructionPromiseResultType *instruction) {
- ZigType *promise_type = ir_resolve_type(ira, instruction->promise_type->child);
- if (type_is_invalid(promise_type))
- return ira->codegen->invalid_instruction;
-
- if (promise_type->id != ZigTypeIdPromise || promise_type->data.promise.result_type == nullptr) {
- ir_add_error(ira, &instruction->base, buf_sprintf("expected promise->T, found '%s'",
- buf_ptr(&promise_type->name)));
- return ira->codegen->invalid_instruction;
- }
-
- return ir_const_type(ira, &instruction->base, promise_type->data.promise.result_type);
-}
-
-static IrInstruction *ir_analyze_instruction_await_bookkeeping(IrAnalyze *ira, IrInstructionAwaitBookkeeping *instruction) {
- ZigType *promise_result_type = ir_resolve_type(ira, instruction->promise_result_type->child);
- if (type_is_invalid(promise_result_type))
- return ira->codegen->invalid_instruction;
-
- ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
- ir_assert(fn_entry != nullptr, &instruction->base);
-
- if (type_can_fail(promise_result_type)) {
- fn_entry->calls_or_awaits_errorable_fn = true;
- }
-
- return ir_const_void(ira, &instruction->base);
-}
-
-static IrInstruction *ir_analyze_instruction_merge_err_ret_traces(IrAnalyze *ira,
- IrInstructionMergeErrRetTraces *instruction)
-{
- IrInstruction *coro_promise_ptr = instruction->coro_promise_ptr->child;
- if (type_is_invalid(coro_promise_ptr->value.type))
- return ira->codegen->invalid_instruction;
-
- ir_assert(coro_promise_ptr->value.type->id == ZigTypeIdPointer, &instruction->base);
- ZigType *promise_frame_type = coro_promise_ptr->value.type->data.pointer.child_type;
- ir_assert(promise_frame_type->id == ZigTypeIdStruct, &instruction->base);
- ZigType *promise_result_type = promise_frame_type->data.structure.fields[1].type_entry;
-
- if (!type_can_fail(promise_result_type)) {
- return ir_const_void(ira, &instruction->base);
- }
-
- IrInstruction *src_err_ret_trace_ptr = instruction->src_err_ret_trace_ptr->child;
- if (type_is_invalid(src_err_ret_trace_ptr->value.type))
- return ira->codegen->invalid_instruction;
-
- IrInstruction *dest_err_ret_trace_ptr = instruction->dest_err_ret_trace_ptr->child;
- if (type_is_invalid(dest_err_ret_trace_ptr->value.type))
- return ira->codegen->invalid_instruction;
-
- IrInstruction *result = ir_build_merge_err_ret_traces(&ira->new_irb, instruction->base.scope,
- instruction->base.source_node, coro_promise_ptr, src_err_ret_trace_ptr, dest_err_ret_trace_ptr);
- result->value.type = ira->codegen->builtin_types.entry_void;
- return result;
-}
-
static IrInstruction *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, IrInstructionSaveErrRetAddr *instruction) {
IrInstruction *result = ir_build_save_err_ret_addr(&ira->new_irb, instruction->base.scope,
instruction->base.source_node);
@@ -25530,8 +24096,6 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
return ir_analyze_instruction_asm(ira, (IrInstructionAsm *)instruction);
case IrInstructionIdArrayType:
return ir_analyze_instruction_array_type(ira, (IrInstructionArrayType *)instruction);
- case IrInstructionIdPromiseType:
- return ir_analyze_instruction_promise_type(ira, (IrInstructionPromiseType *)instruction);
case IrInstructionIdSizeOf:
return ir_analyze_instruction_size_of(ira, (IrInstructionSizeOf *)instruction);
case IrInstructionIdTestNonNull:
@@ -25704,46 +24268,14 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
return ir_analyze_instruction_error_union(ira, (IrInstructionErrorUnion *)instruction);
case IrInstructionIdCancel:
return ir_analyze_instruction_cancel(ira, (IrInstructionCancel *)instruction);
- case IrInstructionIdCoroId:
- return ir_analyze_instruction_coro_id(ira, (IrInstructionCoroId *)instruction);
- case IrInstructionIdCoroAlloc:
- return ir_analyze_instruction_coro_alloc(ira, (IrInstructionCoroAlloc *)instruction);
- case IrInstructionIdCoroSize:
- return ir_analyze_instruction_coro_size(ira, (IrInstructionCoroSize *)instruction);
- case IrInstructionIdCoroBegin:
- return ir_analyze_instruction_coro_begin(ira, (IrInstructionCoroBegin *)instruction);
- case IrInstructionIdGetImplicitAllocator:
- return ir_analyze_instruction_get_implicit_allocator(ira, (IrInstructionGetImplicitAllocator *)instruction);
- case IrInstructionIdCoroAllocFail:
- return ir_analyze_instruction_coro_alloc_fail(ira, (IrInstructionCoroAllocFail *)instruction);
- case IrInstructionIdCoroSuspend:
- return ir_analyze_instruction_coro_suspend(ira, (IrInstructionCoroSuspend *)instruction);
- case IrInstructionIdCoroEnd:
- return ir_analyze_instruction_coro_end(ira, (IrInstructionCoroEnd *)instruction);
- case IrInstructionIdCoroFree:
- return ir_analyze_instruction_coro_free(ira, (IrInstructionCoroFree *)instruction);
- case IrInstructionIdCoroResume:
- return ir_analyze_instruction_coro_resume(ira, (IrInstructionCoroResume *)instruction);
- case IrInstructionIdCoroSave:
- return ir_analyze_instruction_coro_save(ira, (IrInstructionCoroSave *)instruction);
- case IrInstructionIdCoroPromise:
- return ir_analyze_instruction_coro_promise(ira, (IrInstructionCoroPromise *)instruction);
- case IrInstructionIdCoroAllocHelper:
- return ir_analyze_instruction_coro_alloc_helper(ira, (IrInstructionCoroAllocHelper *)instruction);
case IrInstructionIdAtomicRmw:
return ir_analyze_instruction_atomic_rmw(ira, (IrInstructionAtomicRmw *)instruction);
case IrInstructionIdAtomicLoad:
return ir_analyze_instruction_atomic_load(ira, (IrInstructionAtomicLoad *)instruction);
- case IrInstructionIdPromiseResultType:
- return ir_analyze_instruction_promise_result_type(ira, (IrInstructionPromiseResultType *)instruction);
- case IrInstructionIdAwaitBookkeeping:
- return ir_analyze_instruction_await_bookkeeping(ira, (IrInstructionAwaitBookkeeping *)instruction);
case IrInstructionIdSaveErrRetAddr:
return ir_analyze_instruction_save_err_ret_addr(ira, (IrInstructionSaveErrRetAddr *)instruction);
case IrInstructionIdAddImplicitReturnType:
return ir_analyze_instruction_add_implicit_return_type(ira, (IrInstructionAddImplicitReturnType *)instruction);
- case IrInstructionIdMergeErrRetTraces:
- return ir_analyze_instruction_merge_err_ret_traces(ira, (IrInstructionMergeErrRetTraces *)instruction);
case IrInstructionIdMarkErrRetTracePtr:
return ir_analyze_instruction_mark_err_ret_trace_ptr(ira, (IrInstructionMarkErrRetTracePtr *)instruction);
case IrInstructionIdFloatOp:
@@ -25788,9 +24320,7 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_
old_exec->analysis = ira;
ira->codegen = codegen;
- ZigFn *fn_entry = exec_fn_entry(old_exec);
- bool is_async = fn_entry != nullptr && fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync;
- ira->explicit_return_type = is_async ? get_promise_type(codegen, expected_type) : expected_type;
+ ira->explicit_return_type = expected_type;
ira->explicit_return_type_source_node = expected_type_source_node;
ira->old_irb.codegen = codegen;
@@ -25889,17 +24419,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdSetAlignStack:
case IrInstructionIdExport:
case IrInstructionIdCancel:
- case IrInstructionIdCoroId:
- case IrInstructionIdCoroBegin:
- case IrInstructionIdCoroAllocFail:
- case IrInstructionIdCoroEnd:
- case IrInstructionIdCoroResume:
- case IrInstructionIdCoroSave:
- case IrInstructionIdCoroAllocHelper:
- case IrInstructionIdAwaitBookkeeping:
case IrInstructionIdSaveErrRetAddr:
case IrInstructionIdAddImplicitReturnType:
- case IrInstructionIdMergeErrRetTraces:
case IrInstructionIdMarkErrRetTracePtr:
case IrInstructionIdAtomicRmw:
case IrInstructionIdCmpxchgGen:
@@ -25933,7 +24454,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdTypeOf:
case IrInstructionIdStructFieldPtr:
case IrInstructionIdArrayType:
- case IrInstructionIdPromiseType:
case IrInstructionIdSliceType:
case IrInstructionIdSizeOf:
case IrInstructionIdTestNonNull:
@@ -25993,13 +24513,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdTagType:
case IrInstructionIdErrorReturnTrace:
case IrInstructionIdErrorUnion:
- case IrInstructionIdGetImplicitAllocator:
- case IrInstructionIdCoroAlloc:
- case IrInstructionIdCoroSize:
- case IrInstructionIdCoroSuspend:
- case IrInstructionIdCoroFree:
- case IrInstructionIdCoroPromise:
- case IrInstructionIdPromiseResultType:
case IrInstructionIdFloatOp:
case IrInstructionIdMulAdd:
case IrInstructionIdAtomicLoad:
diff --git a/src/ir_print.cpp b/src/ir_print.cpp
index 588a9b2882..9ea70ba7ab 100644
--- a/src/ir_print.cpp
+++ b/src/ir_print.cpp
@@ -257,13 +257,7 @@ static void ir_print_result_loc(IrPrint *irp, ResultLoc *result_loc) {
static void ir_print_call_src(IrPrint *irp, IrInstructionCallSrc *call_instruction) {
if (call_instruction->is_async) {
- fprintf(irp->f, "async");
- if (call_instruction->async_allocator != nullptr) {
- fprintf(irp->f, "<");
- ir_print_other_instruction(irp, call_instruction->async_allocator);
- fprintf(irp->f, ">");
- }
- fprintf(irp->f, " ");
+ fprintf(irp->f, "async ");
}
if (call_instruction->fn_entry) {
fprintf(irp->f, "%s", buf_ptr(&call_instruction->fn_entry->symbol_name));
@@ -284,13 +278,7 @@ static void ir_print_call_src(IrPrint *irp, IrInstructionCallSrc *call_instructi
static void ir_print_call_gen(IrPrint *irp, IrInstructionCallGen *call_instruction) {
if (call_instruction->is_async) {
- fprintf(irp->f, "async");
- if (call_instruction->async_allocator != nullptr) {
- fprintf(irp->f, "<");
- ir_print_other_instruction(irp, call_instruction->async_allocator);
- fprintf(irp->f, ">");
- }
- fprintf(irp->f, " ");
+ fprintf(irp->f, "async ");
}
if (call_instruction->fn_entry) {
fprintf(irp->f, "%s", buf_ptr(&call_instruction->fn_entry->symbol_name));
@@ -477,14 +465,6 @@ static void ir_print_array_type(IrPrint *irp, IrInstructionArrayType *instructio
ir_print_other_instruction(irp, instruction->child_type);
}
-static void ir_print_promise_type(IrPrint *irp, IrInstructionPromiseType *instruction) {
- fprintf(irp->f, "promise");
- if (instruction->payload_type != nullptr) {
- fprintf(irp->f, "->");
- ir_print_other_instruction(irp, instruction->payload_type);
- }
-}
-
static void ir_print_slice_type(IrPrint *irp, IrInstructionSliceType *instruction) {
const char *const_kw = instruction->is_const ? "const " : "";
fprintf(irp->f, "[]%s", const_kw);
@@ -1396,105 +1376,6 @@ static void ir_print_cancel(IrPrint *irp, IrInstructionCancel *instruction) {
ir_print_other_instruction(irp, instruction->target);
}
-static void ir_print_get_implicit_allocator(IrPrint *irp, IrInstructionGetImplicitAllocator *instruction) {
- fprintf(irp->f, "@getImplicitAllocator(");
- switch (instruction->id) {
- case ImplicitAllocatorIdArg:
- fprintf(irp->f, "Arg");
- break;
- case ImplicitAllocatorIdLocalVar:
- fprintf(irp->f, "LocalVar");
- break;
- }
- fprintf(irp->f, ")");
-}
-
-static void ir_print_coro_id(IrPrint *irp, IrInstructionCoroId *instruction) {
- fprintf(irp->f, "@coroId(");
- ir_print_other_instruction(irp, instruction->promise_ptr);
- fprintf(irp->f, ")");
-}
-
-static void ir_print_coro_alloc(IrPrint *irp, IrInstructionCoroAlloc *instruction) {
- fprintf(irp->f, "@coroAlloc(");
- ir_print_other_instruction(irp, instruction->coro_id);
- fprintf(irp->f, ")");
-}
-
-static void ir_print_coro_size(IrPrint *irp, IrInstructionCoroSize *instruction) {
- fprintf(irp->f, "@coroSize()");
-}
-
-static void ir_print_coro_begin(IrPrint *irp, IrInstructionCoroBegin *instruction) {
- fprintf(irp->f, "@coroBegin(");
- ir_print_other_instruction(irp, instruction->coro_id);
- fprintf(irp->f, ",");
- ir_print_other_instruction(irp, instruction->coro_mem_ptr);
- fprintf(irp->f, ")");
-}
-
-static void ir_print_coro_alloc_fail(IrPrint *irp, IrInstructionCoroAllocFail *instruction) {
- fprintf(irp->f, "@coroAllocFail(");
- ir_print_other_instruction(irp, instruction->err_val);
- fprintf(irp->f, ")");
-}
-
-static void ir_print_coro_suspend(IrPrint *irp, IrInstructionCoroSuspend *instruction) {
- fprintf(irp->f, "@coroSuspend(");
- if (instruction->save_point != nullptr) {
- ir_print_other_instruction(irp, instruction->save_point);
- } else {
- fprintf(irp->f, "null");
- }
- fprintf(irp->f, ",");
- ir_print_other_instruction(irp, instruction->is_final);
- fprintf(irp->f, ")");
-}
-
-static void ir_print_coro_end(IrPrint *irp, IrInstructionCoroEnd *instruction) {
- fprintf(irp->f, "@coroEnd()");
-}
-
-static void ir_print_coro_free(IrPrint *irp, IrInstructionCoroFree *instruction) {
- fprintf(irp->f, "@coroFree(");
- ir_print_other_instruction(irp, instruction->coro_id);
- fprintf(irp->f, ",");
- ir_print_other_instruction(irp, instruction->coro_handle);
- fprintf(irp->f, ")");
-}
-
-static void ir_print_coro_resume(IrPrint *irp, IrInstructionCoroResume *instruction) {
- fprintf(irp->f, "@coroResume(");
- ir_print_other_instruction(irp, instruction->awaiter_handle);
- fprintf(irp->f, ")");
-}
-
-static void ir_print_coro_save(IrPrint *irp, IrInstructionCoroSave *instruction) {
- fprintf(irp->f, "@coroSave(");
- ir_print_other_instruction(irp, instruction->coro_handle);
- fprintf(irp->f, ")");
-}
-
-static void ir_print_coro_promise(IrPrint *irp, IrInstructionCoroPromise *instruction) {
- fprintf(irp->f, "@coroPromise(");
- ir_print_other_instruction(irp, instruction->coro_handle);
- fprintf(irp->f, ")");
-}
-
-static void ir_print_promise_result_type(IrPrint *irp, IrInstructionPromiseResultType *instruction) {
- fprintf(irp->f, "@PromiseResultType(");
- ir_print_other_instruction(irp, instruction->promise_type);
- fprintf(irp->f, ")");
-}
-
-static void ir_print_coro_alloc_helper(IrPrint *irp, IrInstructionCoroAllocHelper *instruction) {
- fprintf(irp->f, "@coroAllocHelper(");
- ir_print_other_instruction(irp, instruction->realloc_fn);
- fprintf(irp->f, ",");
- ir_print_other_instruction(irp, instruction->coro_size);
- fprintf(irp->f, ")");
-}
-
static void ir_print_atomic_rmw(IrPrint *irp, IrInstructionAtomicRmw *instruction) {
fprintf(irp->f, "@atomicRmw(");
if (instruction->operand_type != nullptr) {
@@ -1539,12 +1420,6 @@ static void ir_print_atomic_load(IrPrint *irp, IrInstructionAtomicLoad *instruct
fprintf(irp->f, ")");
}
-static void ir_print_await_bookkeeping(IrPrint *irp, IrInstructionAwaitBookkeeping *instruction) {
- fprintf(irp->f, "@awaitBookkeeping(");
- ir_print_other_instruction(irp, instruction->promise_result_type);
- fprintf(irp->f, ")");
-}
-
static void ir_print_save_err_ret_addr(IrPrint *irp, IrInstructionSaveErrRetAddr *instruction) {
fprintf(irp->f, "@saveErrRetAddr()");
}
@@ -1555,16 +1430,6 @@ static void ir_print_add_implicit_return_type(IrPrint *irp, IrInstructionAddImpl
fprintf(irp->f, ")");
}
-static void ir_print_merge_err_ret_traces(IrPrint *irp, IrInstructionMergeErrRetTraces *instruction) {
- fprintf(irp->f, "@mergeErrRetTraces(");
- ir_print_other_instruction(irp, instruction->coro_promise_ptr);
- fprintf(irp->f, ",");
- ir_print_other_instruction(irp, instruction->src_err_ret_trace_ptr);
- fprintf(irp->f, ",");
- ir_print_other_instruction(irp, instruction->dest_err_ret_trace_ptr);
- fprintf(irp->f, ")");
-}
-
static void ir_print_mark_err_ret_trace_ptr(IrPrint *irp, IrInstructionMarkErrRetTracePtr *instruction) {
fprintf(irp->f, "@markErrRetTracePtr(");
ir_print_other_instruction(irp, instruction->err_ret_trace_ptr);
@@ -1727,9 +1592,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
case IrInstructionIdArrayType:
ir_print_array_type(irp, (IrInstructionArrayType *)instruction);
break;
- case IrInstructionIdPromiseType:
- ir_print_promise_type(irp, (IrInstructionPromiseType *)instruction);
- break;
case IrInstructionIdSliceType:
ir_print_slice_type(irp, (IrInstructionSliceType *)instruction);
break;
@@ -2033,63 +1895,15 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
case IrInstructionIdCancel:
ir_print_cancel(irp, (IrInstructionCancel *)instruction);
break;
- case IrInstructionIdGetImplicitAllocator:
- ir_print_get_implicit_allocator(irp, (IrInstructionGetImplicitAllocator *)instruction);
- break;
- case IrInstructionIdCoroId:
- ir_print_coro_id(irp, (IrInstructionCoroId *)instruction);
- break;
- case IrInstructionIdCoroAlloc:
- ir_print_coro_alloc(irp, (IrInstructionCoroAlloc *)instruction);
- break;
- case IrInstructionIdCoroSize:
- ir_print_coro_size(irp, (IrInstructionCoroSize *)instruction);
- break;
- case IrInstructionIdCoroBegin:
- ir_print_coro_begin(irp, (IrInstructionCoroBegin *)instruction);
- break;
- case IrInstructionIdCoroAllocFail:
- ir_print_coro_alloc_fail(irp, (IrInstructionCoroAllocFail *)instruction);
- break;
- case IrInstructionIdCoroSuspend:
- ir_print_coro_suspend(irp, (IrInstructionCoroSuspend *)instruction);
- break;
- case IrInstructionIdCoroEnd:
- ir_print_coro_end(irp, (IrInstructionCoroEnd *)instruction);
- break;
- case IrInstructionIdCoroFree:
- ir_print_coro_free(irp, (IrInstructionCoroFree *)instruction);
- break;
- case IrInstructionIdCoroResume:
- ir_print_coro_resume(irp, (IrInstructionCoroResume *)instruction);
- break;
- case IrInstructionIdCoroSave:
- ir_print_coro_save(irp, (IrInstructionCoroSave *)instruction);
- break;
- case IrInstructionIdCoroAllocHelper:
- ir_print_coro_alloc_helper(irp, (IrInstructionCoroAllocHelper *)instruction);
- break;
case IrInstructionIdAtomicRmw:
ir_print_atomic_rmw(irp, (IrInstructionAtomicRmw *)instruction);
break;
- case IrInstructionIdCoroPromise:
- ir_print_coro_promise(irp, (IrInstructionCoroPromise *)instruction);
- break;
- case IrInstructionIdPromiseResultType:
- ir_print_promise_result_type(irp, (IrInstructionPromiseResultType *)instruction);
- break;
- case IrInstructionIdAwaitBookkeeping:
- ir_print_await_bookkeeping(irp, (IrInstructionAwaitBookkeeping *)instruction);
- break;
case IrInstructionIdSaveErrRetAddr:
ir_print_save_err_ret_addr(irp, (IrInstructionSaveErrRetAddr *)instruction);
break;
case IrInstructionIdAddImplicitReturnType:
ir_print_add_implicit_return_type(irp, (IrInstructionAddImplicitReturnType *)instruction);
break;
- case IrInstructionIdMergeErrRetTraces:
- ir_print_merge_err_ret_traces(irp, (IrInstructionMergeErrRetTraces *)instruction);
- break;
case IrInstructionIdMarkErrRetTracePtr:
ir_print_mark_err_ret_trace_ptr(irp, (IrInstructionMarkErrRetTracePtr *)instruction);
break;
diff --git a/src/parser.cpp b/src/parser.cpp
index fe1f89ac92..b1a593d9c9 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -282,9 +282,6 @@ static AstNode *ast_parse_prefix_op_expr(
case NodeTypeAwaitExpr:
right = &prefix->data.await_expr.expr;
break;
- case NodeTypePromiseType:
- right = &prefix->data.promise_type.payload_type;
- break;
case NodeTypeArrayType:
right = &prefix->data.array_type.child_type;
break;
@@ -1643,10 +1640,6 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
if (null != nullptr)
return ast_create_node(pc, NodeTypeNullLiteral, null);
- Token *promise = eat_token_if(pc, TokenIdKeywordPromise);
- if (promise != nullptr)
- return ast_create_node(pc, NodeTypePromiseType, promise);
-
Token *true_token = eat_token_if(pc, TokenIdKeywordTrue);
if (true_token != nullptr) {
AstNode *res = ast_create_node(pc, NodeTypeBoolLiteral, true_token);
@@ -2042,11 +2035,6 @@ static Optional ast_parse_fn_cc(ParseContext *pc) {
}
if (eat_token_if(pc, TokenIdKeywordAsync) != nullptr) {
res.cc = CallingConventionAsync;
- if (eat_token_if(pc, TokenIdCmpLessThan) == nullptr)
- return Optional::some(res);
-
- res.async_allocator_type = ast_expect(pc, ast_parse_type_expr);
- expect_token(pc, TokenIdCmpGreaterThan);
return Optional::some(res);
}
@@ -2533,16 +2521,6 @@ static AstNode *ast_parse_prefix_type_op(ParseContext *pc) {
return res;
}
- Token *promise = eat_token_if(pc, TokenIdKeywordPromise);
- if (promise != nullptr) {
- if (eat_token_if(pc, TokenIdArrow) != nullptr) {
- AstNode *res = ast_create_node(pc, NodeTypePromiseType, promise);
- return res;
- }
-
- put_back_token(pc);
- }
-
AstNode *array = ast_parse_array_type_start(pc);
if (array != nullptr) {
assert(array->type == NodeTypeArrayType);
@@ -2680,11 +2658,6 @@ static AstNode *ast_parse_async_prefix(ParseContext *pc) {
AstNode *res = ast_create_node(pc, NodeTypeFnCallExpr, async);
res->data.fn_call_expr.is_async = true;
res->data.fn_call_expr.seen = false;
- if (eat_token_if(pc, TokenIdCmpLessThan) != nullptr) {
- AstNode *prefix_expr = ast_expect(pc, ast_parse_prefix_expr);
- expect_token(pc, TokenIdCmpGreaterThan);
- res->data.fn_call_expr.async_allocator = prefix_expr;
- }
return res;
}
@@ -2858,7 +2831,6 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
visit_node_list(&node->data.fn_proto.params, visit, context);
visit_field(&node->data.fn_proto.align_expr, visit, context);
visit_field(&node->data.fn_proto.section_expr, visit, context);
- visit_field(&node->data.fn_proto.async_allocator_type, visit, context);
break;
case NodeTypeFnDef:
visit_field(&node->data.fn_def.fn_proto, visit, context);
@@ -2918,7 +2890,6 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
case NodeTypeFnCallExpr:
visit_field(&node->data.fn_call_expr.fn_ref_expr, visit, context);
visit_node_list(&node->data.fn_call_expr.params, visit, context);
- visit_field(&node->data.fn_call_expr.async_allocator, visit, context);
break;
case NodeTypeArrayAccessExpr:
visit_field(&node->data.array_access_expr.array_ref_expr, visit, context);
@@ -3034,9 +3005,6 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
case NodeTypeInferredArrayType:
visit_field(&node->data.array_type.child_type, visit, context);
break;
- case NodeTypePromiseType:
- visit_field(&node->data.promise_type.payload_type, visit, context);
- break;
case NodeTypeErrorType:
// none
break;
diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp
index 783b6e0e20..0869c3ba9c 100644
--- a/src/tokenizer.cpp
+++ b/src/tokenizer.cpp
@@ -136,7 +136,6 @@ static const struct ZigKeyword zig_keywords[] = {
{"or", TokenIdKeywordOr},
{"orelse", TokenIdKeywordOrElse},
{"packed", TokenIdKeywordPacked},
- {"promise", TokenIdKeywordPromise},
{"pub", TokenIdKeywordPub},
{"resume", TokenIdKeywordResume},
{"return", TokenIdKeywordReturn},
@@ -1558,7 +1557,6 @@ const char * token_name(TokenId id) {
case TokenIdKeywordOr: return "or";
case TokenIdKeywordOrElse: return "orelse";
case TokenIdKeywordPacked: return "packed";
- case TokenIdKeywordPromise: return "promise";
case TokenIdKeywordPub: return "pub";
case TokenIdKeywordReturn: return "return";
case TokenIdKeywordLinkSection: return "linksection";
diff --git a/src/tokenizer.hpp b/src/tokenizer.hpp
index 83dbe99471..253e0bd1e5 100644
--- a/src/tokenizer.hpp
+++ b/src/tokenizer.hpp
@@ -81,7 +81,6 @@ enum TokenId {
TokenIdKeywordOr,
TokenIdKeywordOrElse,
TokenIdKeywordPacked,
- TokenIdKeywordPromise,
TokenIdKeywordPub,
TokenIdKeywordResume,
TokenIdKeywordReturn,
diff --git a/std/fmt.zig b/std/fmt.zig
index 2e9527f4ca..961c7279a2 100644
--- a/std/fmt.zig
+++ b/std/fmt.zig
@@ -328,9 +328,6 @@ pub fn formatType(
try output(context, "error.");
return output(context, @errorName(value));
},
- .Promise => {
- return format(context, Errors, output, "promise@{x}", @ptrToInt(value));
- },
.Enum => {
if (comptime std.meta.trait.hasFn("format")(T)) {
return value.format(fmt, options, context, Errors, output);
diff --git a/std/hash_map.zig b/std/hash_map.zig
index c99d1d2490..4327bfdddb 100644
--- a/std/hash_map.zig
+++ b/std/hash_map.zig
@@ -560,7 +560,7 @@ pub fn autoHash(key: var, comptime rng: *std.rand.Random, comptime HashInt: type
builtin.TypeId.Bool => return autoHash(@boolToInt(key), rng, HashInt),
builtin.TypeId.Enum => return autoHash(@enumToInt(key), rng, HashInt),
builtin.TypeId.ErrorSet => return autoHash(@errorToInt(key), rng, HashInt),
- builtin.TypeId.Promise, builtin.TypeId.Fn => return autoHash(@ptrToInt(key), rng, HashInt),
+ builtin.TypeId.Fn => return autoHash(@ptrToInt(key), rng, HashInt),
builtin.TypeId.BoundFn,
builtin.TypeId.ComptimeFloat,
diff --git a/std/meta.zig b/std/meta.zig
index 0db76ce774..6b90727737 100644
--- a/std/meta.zig
+++ b/std/meta.zig
@@ -104,8 +104,7 @@ pub fn Child(comptime T: type) type {
TypeId.Array => |info| info.child,
TypeId.Pointer => |info| info.child,
TypeId.Optional => |info| info.child,
- TypeId.Promise => |info| if (info.child) |child| child else null,
- else => @compileError("Expected promise, pointer, optional, or array type, " ++ "found '" ++ @typeName(T) ++ "'"),
+ else => @compileError("Expected pointer, optional, or array type, " ++ "found '" ++ @typeName(T) ++ "'"),
};
}
@@ -114,7 +113,6 @@ test "std.meta.Child" {
testing.expect(Child(*u8) == u8);
testing.expect(Child([]u8) == u8);
testing.expect(Child(?u8) == u8);
- testing.expect(Child(promise->u8) == u8);
}
pub fn containerLayout(comptime T: type) TypeInfo.ContainerLayout {
diff --git a/std/testing.zig b/std/testing.zig
index 4568e024e2..84f6cff5d8 100644
--- a/std/testing.zig
+++ b/std/testing.zig
@@ -45,7 +45,6 @@ pub fn expectEqual(expected: var, actual: @typeOf(expected)) void {
TypeId.EnumLiteral,
TypeId.Enum,
TypeId.Fn,
- TypeId.Promise,
TypeId.Vector,
TypeId.ErrorSet,
=> {
diff --git a/test/stage1/behavior.zig b/test/stage1/behavior.zig
index 71af5586ed..7950088348 100644
--- a/test/stage1/behavior.zig
+++ b/test/stage1/behavior.zig
@@ -39,11 +39,11 @@ comptime {
_ = @import("behavior/bugs/828.zig");
_ = @import("behavior/bugs/920.zig");
_ = @import("behavior/byval_arg_var.zig");
- _ = @import("behavior/cancel.zig");
+ //_ = @import("behavior/cancel.zig");
_ = @import("behavior/cast.zig");
_ = @import("behavior/const_slice_child.zig");
- _ = @import("behavior/coroutine_await_struct.zig");
- _ = @import("behavior/coroutines.zig");
+ //_ = @import("behavior/coroutine_await_struct.zig");
+ //_ = @import("behavior/coroutines.zig");
_ = @import("behavior/defer.zig");
_ = @import("behavior/enum.zig");
_ = @import("behavior/enum_with_members.zig");
diff --git a/test/stage1/behavior/type_info.zig b/test/stage1/behavior/type_info.zig
index 4ae81aff20..2decf0c329 100644
--- a/test/stage1/behavior/type_info.zig
+++ b/test/stage1/behavior/type_info.zig
@@ -116,21 +116,6 @@ fn testOptional() void {
expect(null_info.Optional.child == void);
}
-test "type info: promise info" {
- testPromise();
- comptime testPromise();
-}
-
-fn testPromise() void {
- const null_promise_info = @typeInfo(promise);
- expect(TypeId(null_promise_info) == TypeId.Promise);
- expect(null_promise_info.Promise.child == null);
-
- const promise_info = @typeInfo(promise->usize);
- expect(TypeId(promise_info) == TypeId.Promise);
- expect(promise_info.Promise.child.? == usize);
-}
-
test "type info: error set, error union info" {
testErrorSet();
comptime testErrorSet();
@@ -192,11 +177,11 @@ fn testUnion() void {
expect(TypeId(typeinfo_info) == TypeId.Union);
expect(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);
expect(typeinfo_info.Union.tag_type.? == TypeId);
- expect(typeinfo_info.Union.fields.len == 25);
+ expect(typeinfo_info.Union.fields.len == 24);
expect(typeinfo_info.Union.fields[4].enum_field != null);
expect(typeinfo_info.Union.fields[4].enum_field.?.value == 4);
expect(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int));
- expect(typeinfo_info.Union.decls.len == 21);
+ expect(typeinfo_info.Union.decls.len == 20);
const TestNoTagUnion = union {
Foo: void,
@@ -265,7 +250,6 @@ fn testFunction() void {
expect(fn_info.Fn.args.len == 2);
expect(fn_info.Fn.is_var_args);
expect(fn_info.Fn.return_type == null);
- expect(fn_info.Fn.async_allocator_type == null);
const test_instance: TestStruct = undefined;
const bound_fn_info = @typeInfo(@typeOf(test_instance.foo));
--
cgit v1.2.3
From ee64a22045ccbc39773779d4e386e25f563c8a90 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Fri, 26 Jul 2019 19:52:35 -0400
Subject: add the `anyframe` and `anyframe->T` types
---
BRANCH_TODO | 6 +-
src/all_types.hpp | 21 +++++++
src/analyze.cpp | 111 ++++++++++++++++++++++++++++++++++++-
src/analyze.hpp | 1 +
src/ast_render.cpp | 10 ++++
src/codegen.cpp | 16 +++++-
src/ir.cpp | 86 +++++++++++++++++++++++++++-
src/ir_print.cpp | 12 ++++
src/parser.cpp | 22 +++++++-
src/tokenizer.cpp | 2 +
src/tokenizer.hpp | 1 +
std/hash_map.zig | 1 +
std/testing.zig | 1 +
std/zig/ast.zig | 16 +++---
std/zig/parse.zig | 40 ++++++-------
std/zig/parser_test.zig | 4 +-
std/zig/render.zig | 10 ++--
std/zig/tokenizer.zig | 4 +-
test/stage1/behavior/type_info.zig | 23 +++++++-
19 files changed, 337 insertions(+), 50 deletions(-)
(limited to 'src/parser.cpp')
diff --git a/BRANCH_TODO b/BRANCH_TODO
index d10bc704d8..e2c4fec436 100644
--- a/BRANCH_TODO
+++ b/BRANCH_TODO
@@ -1,6 +1,4 @@
- * reimplement @frameSize with Prefix Data
- * reimplement with function splitting rather than switch
- * add the `anyframe` type and `anyframe->T`
+ * make the anyframe type and anyframe->T type work with resume
* await
* await of a non async function
* await in single-threaded mode
@@ -12,3 +10,5 @@
* implicit cast of normal function to async function should be allowed when it is inferred to be async
* go over the commented out tests
* revive std.event.Loop
+ * reimplement with function splitting rather than switch
+ * @typeInfo for @Frame(func)
diff --git a/src/all_types.hpp b/src/all_types.hpp
index c9bdfabb0d..1096feade0 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -479,6 +479,7 @@ enum NodeType {
NodeTypeResume,
NodeTypeAwaitExpr,
NodeTypeSuspend,
+ NodeTypeAnyFrameType,
NodeTypeEnumLiteral,
};
@@ -936,6 +937,10 @@ struct AstNodeSuspend {
AstNode *block;
};
+struct AstNodeAnyFrameType {
+ AstNode *payload_type; // can be NULL
+};
+
struct AstNodeEnumLiteral {
Token *period;
Token *identifier;
@@ -1001,6 +1006,7 @@ struct AstNode {
AstNodeResumeExpr resume_expr;
AstNodeAwaitExpr await_expr;
AstNodeSuspend suspend;
+ AstNodeAnyFrameType anyframe_type;
AstNodeEnumLiteral enum_literal;
} data;
};
@@ -1253,6 +1259,7 @@ enum ZigTypeId {
ZigTypeIdArgTuple,
ZigTypeIdOpaque,
ZigTypeIdCoroFrame,
+ ZigTypeIdAnyFrame,
ZigTypeIdVector,
ZigTypeIdEnumLiteral,
};
@@ -1272,6 +1279,10 @@ struct ZigTypeCoroFrame {
ZigType *locals_struct;
};
+struct ZigTypeAnyFrame {
+ ZigType *result_type; // null if `anyframe` instead of `anyframe->T`
+};
+
struct ZigType {
ZigTypeId id;
Buf name;
@@ -1298,11 +1309,13 @@ struct ZigType {
ZigTypeVector vector;
ZigTypeOpaque opaque;
ZigTypeCoroFrame frame;
+ ZigTypeAnyFrame any_frame;
} data;
// use these fields to make sure we don't duplicate type table entries for the same type
ZigType *pointer_parent[2]; // [0 - mut, 1 - const]
ZigType *optional_parent;
+ ZigType *any_frame_parent;
// If we generate a constant name value for this type, we memoize it here.
// The type of this is array
ConstExprValue *cached_const_name_val;
@@ -1781,6 +1794,7 @@ struct CodeGen {
ZigType *entry_arg_tuple;
ZigType *entry_enum_literal;
ZigType *entry_frame_header;
+ ZigType *entry_any_frame;
} builtin_types;
ZigType *align_amt_type;
ZigType *stack_trace_type;
@@ -2208,6 +2222,7 @@ enum IrInstructionId {
IrInstructionIdSetRuntimeSafety,
IrInstructionIdSetFloatMode,
IrInstructionIdArrayType,
+ IrInstructionIdAnyFrameType,
IrInstructionIdSliceType,
IrInstructionIdGlobalAsm,
IrInstructionIdAsm,
@@ -2709,6 +2724,12 @@ struct IrInstructionPtrType {
bool is_allow_zero;
};
+struct IrInstructionAnyFrameType {
+ IrInstruction base;
+
+ IrInstruction *payload_type;
+};
+
struct IrInstructionSliceType {
IrInstruction base;
diff --git a/src/analyze.cpp b/src/analyze.cpp
index e1fedab7cf..e47be8f14c 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -256,6 +256,7 @@ AstNode *type_decl_node(ZigType *type_entry) {
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdVector:
+ case ZigTypeIdAnyFrame:
return nullptr;
}
zig_unreachable();
@@ -322,6 +323,7 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) {
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdVector:
+ case ZigTypeIdAnyFrame:
return true;
}
zig_unreachable();
@@ -354,6 +356,31 @@ ZigType *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) {
return get_int_type(g, false, bits_needed_for_unsigned(x));
}
+ZigType *get_any_frame_type(CodeGen *g, ZigType *result_type) {
+ if (result_type != nullptr && result_type->any_frame_parent != nullptr) {
+ return result_type->any_frame_parent;
+ } else if (result_type == nullptr && g->builtin_types.entry_any_frame != nullptr) {
+ return g->builtin_types.entry_any_frame;
+ }
+
+ ZigType *entry = new_type_table_entry(ZigTypeIdAnyFrame);
+ entry->abi_size = g->builtin_types.entry_usize->abi_size;
+ entry->size_in_bits = g->builtin_types.entry_usize->size_in_bits;
+ entry->abi_align = g->builtin_types.entry_usize->abi_align;
+ entry->data.any_frame.result_type = result_type;
+ buf_init_from_str(&entry->name, "anyframe");
+ if (result_type != nullptr) {
+ buf_appendf(&entry->name, "->%s", buf_ptr(&result_type->name));
+ }
+
+ if (result_type != nullptr) {
+ result_type->any_frame_parent = entry;
+ } else if (result_type == nullptr) {
+ g->builtin_types.entry_any_frame = entry;
+ }
+ return entry;
+}
+
static const char *ptr_len_to_star_str(PtrLen ptr_len) {
switch (ptr_len) {
case PtrLenSingle:
@@ -1080,6 +1107,7 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType
case ZigTypeIdArgTuple:
case ZigTypeIdOpaque:
case ZigTypeIdCoroFrame:
+ case ZigTypeIdAnyFrame:
add_node_error(g, source_node,
buf_sprintf("type '%s' not allowed in packed struct; no guaranteed in-memory representation",
buf_ptr(&type_entry->name)));
@@ -1169,6 +1197,7 @@ bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry) {
case ZigTypeIdArgTuple:
case ZigTypeIdVoid:
case ZigTypeIdCoroFrame:
+ case ZigTypeIdAnyFrame:
return false;
case ZigTypeIdOpaque:
case ZigTypeIdUnreachable:
@@ -1340,6 +1369,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
case ZigTypeIdFn:
case ZigTypeIdVector:
case ZigTypeIdCoroFrame:
+ case ZigTypeIdAnyFrame:
switch (type_requires_comptime(g, type_entry)) {
case ReqCompTimeNo:
break;
@@ -1436,6 +1466,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
case ZigTypeIdFn:
case ZigTypeIdVector:
case ZigTypeIdCoroFrame:
+ case ZigTypeIdAnyFrame:
switch (type_requires_comptime(g, fn_type_id.return_type)) {
case ReqCompTimeInvalid:
return g->builtin_types.entry_invalid;
@@ -2997,6 +3028,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
case NodeTypeAwaitExpr:
case NodeTypeSuspend:
case NodeTypeEnumLiteral:
+ case NodeTypeAnyFrameType:
zig_unreachable();
}
}
@@ -3049,6 +3081,7 @@ ZigType *validate_var_type(CodeGen *g, AstNode *source_node, ZigType *type_entry
case ZigTypeIdBoundFn:
case ZigTypeIdVector:
case ZigTypeIdCoroFrame:
+ case ZigTypeIdAnyFrame:
return type_entry;
}
zig_unreachable();
@@ -3550,6 +3583,7 @@ bool is_container(ZigType *type_entry) {
case ZigTypeIdOpaque:
case ZigTypeIdVector:
case ZigTypeIdCoroFrame:
+ case ZigTypeIdAnyFrame:
return false;
}
zig_unreachable();
@@ -3607,6 +3641,7 @@ Error resolve_container_type(CodeGen *g, ZigType *type_entry) {
case ZigTypeIdOpaque:
case ZigTypeIdVector:
case ZigTypeIdCoroFrame:
+ case ZigTypeIdAnyFrame:
zig_unreachable();
}
zig_unreachable();
@@ -3615,11 +3650,13 @@ Error resolve_container_type(CodeGen *g, ZigType *type_entry) {
ZigType *get_src_ptr_type(ZigType *type) {
if (type->id == ZigTypeIdPointer) return type;
if (type->id == ZigTypeIdFn) return type;
+ if (type->id == ZigTypeIdAnyFrame) return type;
if (type->id == ZigTypeIdOptional) {
if (type->data.maybe.child_type->id == ZigTypeIdPointer) {
return type->data.maybe.child_type->data.pointer.allow_zero ? nullptr : type->data.maybe.child_type;
}
if (type->data.maybe.child_type->id == ZigTypeIdFn) return type->data.maybe.child_type;
+ if (type->data.maybe.child_type->id == ZigTypeIdAnyFrame) return type->data.maybe.child_type;
}
return nullptr;
}
@@ -3635,6 +3672,13 @@ bool type_is_nonnull_ptr(ZigType *type) {
return get_codegen_ptr_type(type) == type && !ptr_allows_addr_zero(type);
}
+static uint32_t get_coro_frame_align_bytes(CodeGen *g) {
+ uint32_t a = g->pointer_size_bytes * 2;
+ // promises have at least alignment 8 so that we can have 3 extra bits when doing atomicrmw
+ if (a < 8) a = 8;
+ return a;
+}
+
uint32_t get_ptr_align(CodeGen *g, ZigType *type) {
ZigType *ptr_type = get_src_ptr_type(type);
if (ptr_type->id == ZigTypeIdPointer) {
@@ -3646,6 +3690,8 @@ uint32_t get_ptr_align(CodeGen *g, ZigType *type) {
// when getting the alignment of `?extern fn() void`.
// See http://lists.llvm.org/pipermail/llvm-dev/2018-September/126142.html
return (ptr_type->data.fn.fn_type_id.alignment == 0) ? 1 : ptr_type->data.fn.fn_type_id.alignment;
+ } else if (ptr_type->id == ZigTypeIdAnyFrame) {
+ return get_coro_frame_align_bytes(g);
} else {
zig_unreachable();
}
@@ -3657,6 +3703,8 @@ bool get_ptr_const(ZigType *type) {
return ptr_type->data.pointer.is_const;
} else if (ptr_type->id == ZigTypeIdFn) {
return true;
+ } else if (ptr_type->id == ZigTypeIdAnyFrame) {
+ return true;
} else {
zig_unreachable();
}
@@ -4153,6 +4201,7 @@ bool handle_is_ptr(ZigType *type_entry) {
case ZigTypeIdFn:
case ZigTypeIdEnum:
case ZigTypeIdVector:
+ case ZigTypeIdAnyFrame:
return false;
case ZigTypeIdArray:
case ZigTypeIdStruct:
@@ -4404,6 +4453,9 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
case ZigTypeIdCoroFrame:
// TODO better hashing algorithm
return 675741936;
+ case ZigTypeIdAnyFrame:
+ // TODO better hashing algorithm
+ return 3747294894;
case ZigTypeIdBoundFn:
case ZigTypeIdInvalid:
case ZigTypeIdUnreachable:
@@ -4469,6 +4521,7 @@ static bool can_mutate_comptime_var_state(ConstExprValue *value) {
case ZigTypeIdErrorSet:
case ZigTypeIdEnum:
case ZigTypeIdCoroFrame:
+ case ZigTypeIdAnyFrame:
return false;
case ZigTypeIdPointer:
@@ -4541,6 +4594,7 @@ static bool return_type_is_cacheable(ZigType *return_type) {
case ZigTypeIdPointer:
case ZigTypeIdVector:
case ZigTypeIdCoroFrame:
+ case ZigTypeIdAnyFrame:
return true;
case ZigTypeIdArray:
@@ -4673,6 +4727,7 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
case ZigTypeIdFloat:
case ZigTypeIdErrorUnion:
case ZigTypeIdCoroFrame:
+ case ZigTypeIdAnyFrame:
return OnePossibleValueNo;
case ZigTypeIdUndefined:
case ZigTypeIdNull:
@@ -4761,6 +4816,7 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry) {
case ZigTypeIdVoid:
case ZigTypeIdUnreachable:
case ZigTypeIdCoroFrame:
+ case ZigTypeIdAnyFrame:
return ReqCompTimeNo;
}
zig_unreachable();
@@ -5433,6 +5489,8 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {
return true;
case ZigTypeIdCoroFrame:
zig_panic("TODO");
+ case ZigTypeIdAnyFrame:
+ zig_panic("TODO");
case ZigTypeIdUndefined:
zig_panic("TODO");
case ZigTypeIdNull:
@@ -5786,7 +5844,11 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
return;
}
case ZigTypeIdCoroFrame:
- buf_appendf(buf, "(TODO: coroutine frame value)");
+ buf_appendf(buf, "(TODO: async function frame value)");
+ return;
+
+ case ZigTypeIdAnyFrame:
+ buf_appendf(buf, "(TODO: anyframe value)");
return;
}
@@ -5836,6 +5898,7 @@ uint32_t type_id_hash(TypeId x) {
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdCoroFrame:
+ case ZigTypeIdAnyFrame:
zig_unreachable();
case ZigTypeIdErrorUnion:
return hash_ptr(x.data.error_union.err_set_type) ^ hash_ptr(x.data.error_union.payload_type);
@@ -5885,6 +5948,7 @@ bool type_id_eql(TypeId a, TypeId b) {
case ZigTypeIdArgTuple:
case ZigTypeIdOpaque:
case ZigTypeIdCoroFrame:
+ case ZigTypeIdAnyFrame:
zig_unreachable();
case ZigTypeIdErrorUnion:
return a.data.error_union.err_set_type == b.data.error_union.err_set_type &&
@@ -6051,6 +6115,7 @@ static const ZigTypeId all_type_ids[] = {
ZigTypeIdArgTuple,
ZigTypeIdOpaque,
ZigTypeIdCoroFrame,
+ ZigTypeIdAnyFrame,
ZigTypeIdVector,
ZigTypeIdEnumLiteral,
};
@@ -6116,10 +6181,12 @@ size_t type_id_index(ZigType *entry) {
return 21;
case ZigTypeIdCoroFrame:
return 22;
- case ZigTypeIdVector:
+ case ZigTypeIdAnyFrame:
return 23;
- case ZigTypeIdEnumLiteral:
+ case ZigTypeIdVector:
return 24;
+ case ZigTypeIdEnumLiteral:
+ return 25;
}
zig_unreachable();
}
@@ -6178,6 +6245,8 @@ const char *type_id_name(ZigTypeId id) {
return "Vector";
case ZigTypeIdCoroFrame:
return "Frame";
+ case ZigTypeIdAnyFrame:
+ return "AnyFrame";
}
zig_unreachable();
}
@@ -7398,6 +7467,40 @@ static void resolve_llvm_types_coro_frame(CodeGen *g, ZigType *frame_type, Resol
frame_type->llvm_di_type = frame_type->data.frame.locals_struct->llvm_di_type;
}
+static void resolve_llvm_types_any_frame(CodeGen *g, ZigType *any_frame_type, ResolveStatus wanted_resolve_status) {
+ if (any_frame_type->llvm_di_type != nullptr) return;
+
+ ZigType *result_type = any_frame_type->data.any_frame.result_type;
+ Buf *name = buf_sprintf("(%s header)", buf_ptr(&any_frame_type->name));
+
+ ZigType *frame_header_type;
+ if (result_type == nullptr || !type_has_bits(result_type)) {
+ const char *field_names[] = {"resume_index", "fn_ptr", "awaiter"};
+ ZigType *field_types[] = {
+ g->builtin_types.entry_usize,
+ g->builtin_types.entry_usize,
+ g->builtin_types.entry_usize,
+ };
+ frame_header_type = get_struct_type(g, buf_ptr(name), field_names, field_types, 3);
+ } else {
+ ZigType *ptr_result_type = get_pointer_to_type(g, result_type, false);
+
+ const char *field_names[] = {"resume_index", "fn_ptr", "awaiter", "result_ptr", "result"};
+ ZigType *field_types[] = {
+ g->builtin_types.entry_usize,
+ g->builtin_types.entry_usize,
+ g->builtin_types.entry_usize,
+ ptr_result_type,
+ result_type,
+ };
+ frame_header_type = get_struct_type(g, buf_ptr(name), field_names, field_types, 5);
+ }
+
+ ZigType *ptr_type = get_pointer_to_type(g, frame_header_type, false);
+ any_frame_type->llvm_type = get_llvm_type(g, ptr_type);
+ any_frame_type->llvm_di_type = get_llvm_di_type(g, ptr_type);
+}
+
static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status) {
assert(type->id == ZigTypeIdOpaque || type_is_resolved(type, ResolveStatusSizeKnown));
assert(wanted_resolve_status > ResolveStatusSizeKnown);
@@ -7460,6 +7563,8 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_r
}
case ZigTypeIdCoroFrame:
return resolve_llvm_types_coro_frame(g, type, wanted_resolve_status);
+ case ZigTypeIdAnyFrame:
+ return resolve_llvm_types_any_frame(g, type, wanted_resolve_status);
}
zig_unreachable();
}
diff --git a/src/analyze.hpp b/src/analyze.hpp
index 47ff4344ba..3115c79b40 100644
--- a/src/analyze.hpp
+++ b/src/analyze.hpp
@@ -41,6 +41,7 @@ ZigType *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const c
ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[],
ZigType *field_types[], size_t field_count);
ZigType *get_test_fn_type(CodeGen *g);
+ZigType *get_any_frame_type(CodeGen *g, ZigType *result_type);
bool handle_is_ptr(ZigType *type_entry);
bool type_has_bits(ZigType *type_entry);
diff --git a/src/ast_render.cpp b/src/ast_render.cpp
index d97f58fdec..4d6bae311b 100644
--- a/src/ast_render.cpp
+++ b/src/ast_render.cpp
@@ -259,6 +259,8 @@ static const char *node_type_str(NodeType node_type) {
return "Suspend";
case NodeTypePointerType:
return "PointerType";
+ case NodeTypeAnyFrameType:
+ return "AnyFrameType";
case NodeTypeEnumLiteral:
return "EnumLiteral";
}
@@ -847,6 +849,14 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
render_node_ungrouped(ar, node->data.inferred_array_type.child_type);
break;
}
+ case NodeTypeAnyFrameType: {
+ fprintf(ar->f, "anyframe");
+ if (node->data.anyframe_type.payload_type != nullptr) {
+ fprintf(ar->f, "->");
+ render_node_grouped(ar, node->data.anyframe_type.payload_type);
+ }
+ break;
+ }
case NodeTypeErrorType:
fprintf(ar->f, "anyerror");
break;
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 63018cb6a3..c666317c17 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -4947,6 +4947,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
case IrInstructionIdSetRuntimeSafety:
case IrInstructionIdSetFloatMode:
case IrInstructionIdArrayType:
+ case IrInstructionIdAnyFrameType:
case IrInstructionIdSliceType:
case IrInstructionIdSizeOf:
case IrInstructionIdSwitchTarget:
@@ -5438,7 +5439,9 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con
return val;
}
case ZigTypeIdCoroFrame:
- zig_panic("TODO bit pack a coroutine frame");
+ zig_panic("TODO bit pack an async function frame");
+ case ZigTypeIdAnyFrame:
+ zig_panic("TODO bit pack an anyframe");
}
zig_unreachable();
}
@@ -5961,6 +5964,8 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
zig_unreachable();
case ZigTypeIdCoroFrame:
zig_panic("TODO");
+ case ZigTypeIdAnyFrame:
+ zig_panic("TODO");
}
zig_unreachable();
}
@@ -7176,6 +7181,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
" ArgTuple: void,\n"
" Opaque: void,\n"
" Frame: void,\n"
+ " AnyFrame: AnyFrame,\n"
" Vector: Vector,\n"
" EnumLiteral: void,\n"
"\n\n"
@@ -7291,6 +7297,10 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
" args: []FnArg,\n"
" };\n"
"\n"
+ " pub const AnyFrame = struct {\n"
+ " child: ?type,\n"
+ " };\n"
+ "\n"
" pub const Vector = struct {\n"
" len: comptime_int,\n"
" child: type,\n"
@@ -8448,6 +8458,7 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_e
case ZigTypeIdErrorUnion:
case ZigTypeIdErrorSet:
case ZigTypeIdCoroFrame:
+ case ZigTypeIdAnyFrame:
zig_unreachable();
case ZigTypeIdVoid:
case ZigTypeIdUnreachable:
@@ -8632,6 +8643,7 @@ static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_bu
case ZigTypeIdNull:
case ZigTypeIdArgTuple:
case ZigTypeIdCoroFrame:
+ case ZigTypeIdAnyFrame:
zig_unreachable();
}
}
@@ -8800,7 +8812,9 @@ static void gen_h_file(CodeGen *g) {
case ZigTypeIdFn:
case ZigTypeIdVector:
case ZigTypeIdCoroFrame:
+ case ZigTypeIdAnyFrame:
zig_unreachable();
+
case ZigTypeIdEnum:
if (type_entry->data.enumeration.layout == ContainerLayoutExtern) {
fprintf(out_h, "enum %s {\n", buf_ptr(type_h_name(type_entry)));
diff --git a/src/ir.cpp b/src/ir.cpp
index 7a5af347b7..e6d987a2ee 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -303,6 +303,7 @@ static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) {
case ZigTypeIdBoundFn:
case ZigTypeIdErrorSet:
case ZigTypeIdOpaque:
+ case ZigTypeIdAnyFrame:
return true;
case ZigTypeIdFloat:
return a->data.floating.bit_count == b->data.floating.bit_count;
@@ -563,6 +564,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayType *) {
return IrInstructionIdArrayType;
}
+static constexpr IrInstructionId ir_instruction_id(IrInstructionAnyFrameType *) {
+ return IrInstructionIdAnyFrameType;
+}
+
static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceType *) {
return IrInstructionIdSliceType;
}
@@ -1696,6 +1701,16 @@ static IrInstruction *ir_build_array_type(IrBuilder *irb, Scope *scope, AstNode
return &instruction->base;
}
+static IrInstruction *ir_build_anyframe_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
+ IrInstruction *payload_type)
+{
+ IrInstructionAnyFrameType *instruction = ir_build_instruction(irb, scope, source_node);
+ instruction->payload_type = payload_type;
+
+ if (payload_type != nullptr) ir_ref_instruction(payload_type, irb->current_basic_block);
+
+ return &instruction->base;
+}
static IrInstruction *ir_build_slice_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
IrInstruction *child_type, bool is_const, bool is_volatile, IrInstruction *align_value, bool is_allow_zero)
{
@@ -6515,6 +6530,22 @@ static IrInstruction *ir_gen_array_type(IrBuilder *irb, Scope *scope, AstNode *n
}
}
+static IrInstruction *ir_gen_anyframe_type(IrBuilder *irb, Scope *scope, AstNode *node) {
+ assert(node->type == NodeTypeAnyFrameType);
+
+ AstNode *payload_type_node = node->data.anyframe_type.payload_type;
+ IrInstruction *payload_type_value = nullptr;
+
+ if (payload_type_node != nullptr) {
+ payload_type_value = ir_gen_node(irb, payload_type_node, scope);
+ if (payload_type_value == irb->codegen->invalid_instruction)
+ return payload_type_value;
+
+ }
+
+ return ir_build_anyframe_type(irb, scope, node, payload_type_value);
+}
+
static IrInstruction *ir_gen_undefined_literal(IrBuilder *irb, Scope *scope, AstNode *node) {
assert(node->type == NodeTypeUndefinedLiteral);
return ir_build_const_undefined(irb, scope, node);
@@ -7884,6 +7915,8 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
return ir_lval_wrap(irb, scope, ir_gen_array_type(irb, scope, node), lval, result_loc);
case NodeTypePointerType:
return ir_lval_wrap(irb, scope, ir_gen_pointer_type(irb, scope, node), lval, result_loc);
+ case NodeTypeAnyFrameType:
+ return ir_lval_wrap(irb, scope, ir_gen_anyframe_type(irb, scope, node), lval, result_loc);
case NodeTypeStringLiteral:
return ir_lval_wrap(irb, scope, ir_gen_string_literal(irb, scope, node), lval, result_loc);
case NodeTypeUndefinedLiteral:
@@ -12775,6 +12808,7 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *
case ZigTypeIdArgTuple:
case ZigTypeIdEnum:
case ZigTypeIdEnumLiteral:
+ case ZigTypeIdAnyFrame:
operator_allowed = is_equality_cmp;
break;
@@ -14155,6 +14189,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
case ZigTypeIdArgTuple:
case ZigTypeIdOpaque:
case ZigTypeIdCoroFrame:
+ case ZigTypeIdAnyFrame:
ir_add_error(ira, target,
buf_sprintf("invalid export target '%s'", buf_ptr(&type_value->name)));
break;
@@ -14180,6 +14215,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
case ZigTypeIdOpaque:
case ZigTypeIdEnumLiteral:
case ZigTypeIdCoroFrame:
+ case ZigTypeIdAnyFrame:
ir_add_error(ira, target,
buf_sprintf("invalid export target type '%s'", buf_ptr(&target->value.type->name)));
break;
@@ -15720,7 +15756,9 @@ static IrInstruction *ir_analyze_optional_type(IrAnalyze *ira, IrInstructionUnOp
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdCoroFrame:
+ case ZigTypeIdAnyFrame:
return ir_const_type(ira, &un_op_instruction->base, get_optional_type(ira->codegen, type_entry));
+
case ZigTypeIdUnreachable:
case ZigTypeIdOpaque:
ir_add_error_node(ira, un_op_instruction->base.source_node,
@@ -17443,6 +17481,20 @@ static IrInstruction *ir_analyze_instruction_set_float_mode(IrAnalyze *ira,
return ir_const_void(ira, &instruction->base);
}
+static IrInstruction *ir_analyze_instruction_any_frame_type(IrAnalyze *ira,
+ IrInstructionAnyFrameType *instruction)
+{
+ ZigType *payload_type = nullptr;
+ if (instruction->payload_type != nullptr) {
+ payload_type = ir_resolve_type(ira, instruction->payload_type->child);
+ if (type_is_invalid(payload_type))
+ return ira->codegen->invalid_instruction;
+ }
+
+ ZigType *any_frame_type = get_any_frame_type(ira->codegen, payload_type);
+ return ir_const_type(ira, &instruction->base, any_frame_type);
+}
+
static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira,
IrInstructionSliceType *slice_type_instruction)
{
@@ -17492,6 +17544,7 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira,
case ZigTypeIdBoundFn:
case ZigTypeIdVector:
case ZigTypeIdCoroFrame:
+ case ZigTypeIdAnyFrame:
{
ResolveStatus needed_status = (align_bytes == 0) ?
ResolveStatusZeroBitsKnown : ResolveStatusAlignmentKnown;
@@ -17607,6 +17660,7 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira,
case ZigTypeIdBoundFn:
case ZigTypeIdVector:
case ZigTypeIdCoroFrame:
+ case ZigTypeIdAnyFrame:
{
if ((err = ensure_complete_type(ira->codegen, child_type)))
return ira->codegen->invalid_instruction;
@@ -17658,6 +17712,7 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira,
case ZigTypeIdFn:
case ZigTypeIdVector:
case ZigTypeIdCoroFrame:
+ case ZigTypeIdAnyFrame:
{
uint64_t size_in_bytes = type_size(ira->codegen, type_entry);
return ir_const_unsigned(ira, &size_of_instruction->base, size_in_bytes);
@@ -18222,6 +18277,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,
case ZigTypeIdOpaque:
case ZigTypeIdVector:
case ZigTypeIdCoroFrame:
+ case ZigTypeIdAnyFrame:
ir_add_error(ira, &switch_target_instruction->base,
buf_sprintf("invalid switch target type '%s'", buf_ptr(&target_type->name)));
return ira->codegen->invalid_instruction;
@@ -19656,6 +19712,22 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
break;
}
+ case ZigTypeIdAnyFrame: {
+ result = create_const_vals(1);
+ result->special = ConstValSpecialStatic;
+ result->type = ir_type_info_get_type(ira, "AnyFrame", nullptr);
+
+ ConstExprValue *fields = create_const_vals(1);
+ result->data.x_struct.fields = fields;
+
+ // child: ?type
+ ensure_field_index(result->type, "child", 0);
+ fields[0].special = ConstValSpecialStatic;
+ fields[0].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type);
+ fields[0].data.x_optional = (type_entry->data.any_frame.result_type == nullptr) ? nullptr :
+ create_const_type(ira->codegen, type_entry->data.any_frame.result_type);
+ break;
+ }
case ZigTypeIdEnum:
{
result = create_const_vals(1);
@@ -20062,7 +20134,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
break;
}
case ZigTypeIdCoroFrame:
- zig_panic("TODO @typeInfo for coro frames");
+ zig_panic("TODO @typeInfo for async function frames");
}
assert(result != nullptr);
@@ -21852,6 +21924,7 @@ static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruct
case ZigTypeIdFn:
case ZigTypeIdVector:
case ZigTypeIdCoroFrame:
+ case ZigTypeIdAnyFrame:
{
uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry);
return ir_const_unsigned(ira, &instruction->base, align_in_bytes);
@@ -23004,7 +23077,9 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
case ZigTypeIdUnion:
zig_panic("TODO buf_write_value_bytes union type");
case ZigTypeIdCoroFrame:
- zig_panic("TODO buf_write_value_bytes coro frame type");
+ zig_panic("TODO buf_write_value_bytes async fn frame type");
+ case ZigTypeIdAnyFrame:
+ zig_panic("TODO buf_write_value_bytes anyframe type");
}
zig_unreachable();
}
@@ -23185,7 +23260,9 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
case ZigTypeIdUnion:
zig_panic("TODO buf_read_value_bytes union type");
case ZigTypeIdCoroFrame:
- zig_panic("TODO buf_read_value_bytes coro frame type");
+ zig_panic("TODO buf_read_value_bytes async fn frame type");
+ case ZigTypeIdAnyFrame:
+ zig_panic("TODO buf_read_value_bytes anyframe type");
}
zig_unreachable();
}
@@ -24327,6 +24404,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
return ir_analyze_instruction_set_runtime_safety(ira, (IrInstructionSetRuntimeSafety *)instruction);
case IrInstructionIdSetFloatMode:
return ir_analyze_instruction_set_float_mode(ira, (IrInstructionSetFloatMode *)instruction);
+ case IrInstructionIdAnyFrameType:
+ return ir_analyze_instruction_any_frame_type(ira, (IrInstructionAnyFrameType *)instruction);
case IrInstructionIdSliceType:
return ir_analyze_instruction_slice_type(ira, (IrInstructionSliceType *)instruction);
case IrInstructionIdGlobalAsm:
@@ -24707,6 +24786,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdStructFieldPtr:
case IrInstructionIdArrayType:
case IrInstructionIdSliceType:
+ case IrInstructionIdAnyFrameType:
case IrInstructionIdSizeOf:
case IrInstructionIdTestNonNull:
case IrInstructionIdOptionalUnwrapPtr:
diff --git a/src/ir_print.cpp b/src/ir_print.cpp
index ae467bdc8c..284ebed2f3 100644
--- a/src/ir_print.cpp
+++ b/src/ir_print.cpp
@@ -471,6 +471,15 @@ static void ir_print_slice_type(IrPrint *irp, IrInstructionSliceType *instructio
ir_print_other_instruction(irp, instruction->child_type);
}
+static void ir_print_any_frame_type(IrPrint *irp, IrInstructionAnyFrameType *instruction) {
+ if (instruction->payload_type == nullptr) {
+ fprintf(irp->f, "anyframe");
+ } else {
+ fprintf(irp->f, "anyframe->");
+ ir_print_other_instruction(irp, instruction->payload_type);
+ }
+}
+
static void ir_print_global_asm(IrPrint *irp, IrInstructionGlobalAsm *instruction) {
fprintf(irp->f, "asm(\"%s\")", buf_ptr(instruction->asm_code));
}
@@ -1629,6 +1638,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
case IrInstructionIdSliceType:
ir_print_slice_type(irp, (IrInstructionSliceType *)instruction);
break;
+ case IrInstructionIdAnyFrameType:
+ ir_print_any_frame_type(irp, (IrInstructionAnyFrameType *)instruction);
+ break;
case IrInstructionIdGlobalAsm:
ir_print_global_asm(irp, (IrInstructionGlobalAsm *)instruction);
break;
diff --git a/src/parser.cpp b/src/parser.cpp
index b1a593d9c9..82312aacf3 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -282,6 +282,9 @@ static AstNode *ast_parse_prefix_op_expr(
case NodeTypeAwaitExpr:
right = &prefix->data.await_expr.expr;
break;
+ case NodeTypeAnyFrameType:
+ right = &prefix->data.anyframe_type.payload_type;
+ break;
case NodeTypeArrayType:
right = &prefix->data.array_type.child_type;
break;
@@ -1640,6 +1643,10 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
if (null != nullptr)
return ast_create_node(pc, NodeTypeNullLiteral, null);
+ Token *anyframe = eat_token_if(pc, TokenIdKeywordAnyFrame);
+ if (anyframe != nullptr)
+ return ast_create_node(pc, NodeTypeAnyFrameType, anyframe);
+
Token *true_token = eat_token_if(pc, TokenIdKeywordTrue);
if (true_token != nullptr) {
AstNode *res = ast_create_node(pc, NodeTypeBoolLiteral, true_token);
@@ -2510,7 +2517,7 @@ static AstNode *ast_parse_prefix_op(ParseContext *pc) {
// PrefixTypeOp
// <- QUESTIONMARK
-// / KEYWORD_promise MINUSRARROW
+// / KEYWORD_anyframe MINUSRARROW
// / ArrayTypeStart (ByteAlign / KEYWORD_const / KEYWORD_volatile)*
// / PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile)*
static AstNode *ast_parse_prefix_type_op(ParseContext *pc) {
@@ -2521,6 +2528,16 @@ static AstNode *ast_parse_prefix_type_op(ParseContext *pc) {
return res;
}
+ Token *anyframe = eat_token_if(pc, TokenIdKeywordAnyFrame);
+ if (anyframe != nullptr) {
+ if (eat_token_if(pc, TokenIdArrow) != nullptr) {
+ AstNode *res = ast_create_node(pc, NodeTypeAnyFrameType, anyframe);
+ return res;
+ }
+
+ put_back_token(pc);
+ }
+
AstNode *array = ast_parse_array_type_start(pc);
if (array != nullptr) {
assert(array->type == NodeTypeArrayType);
@@ -3005,6 +3022,9 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
case NodeTypeInferredArrayType:
visit_field(&node->data.array_type.child_type, visit, context);
break;
+ case NodeTypeAnyFrameType:
+ visit_field(&node->data.anyframe_type.payload_type, visit, context);
+ break;
case NodeTypeErrorType:
// none
break;
diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp
index 0869c3ba9c..38c6c7153e 100644
--- a/src/tokenizer.cpp
+++ b/src/tokenizer.cpp
@@ -109,6 +109,7 @@ static const struct ZigKeyword zig_keywords[] = {
{"align", TokenIdKeywordAlign},
{"allowzero", TokenIdKeywordAllowZero},
{"and", TokenIdKeywordAnd},
+ {"anyframe", TokenIdKeywordAnyFrame},
{"asm", TokenIdKeywordAsm},
{"async", TokenIdKeywordAsync},
{"await", TokenIdKeywordAwait},
@@ -1533,6 +1534,7 @@ const char * token_name(TokenId id) {
case TokenIdKeywordCancel: return "cancel";
case TokenIdKeywordAlign: return "align";
case TokenIdKeywordAnd: return "and";
+ case TokenIdKeywordAnyFrame: return "anyframe";
case TokenIdKeywordAsm: return "asm";
case TokenIdKeywordBreak: return "break";
case TokenIdKeywordCatch: return "catch";
diff --git a/src/tokenizer.hpp b/src/tokenizer.hpp
index 253e0bd1e5..98bdfea907 100644
--- a/src/tokenizer.hpp
+++ b/src/tokenizer.hpp
@@ -53,6 +53,7 @@ enum TokenId {
TokenIdKeywordAlign,
TokenIdKeywordAllowZero,
TokenIdKeywordAnd,
+ TokenIdKeywordAnyFrame,
TokenIdKeywordAsm,
TokenIdKeywordAsync,
TokenIdKeywordAwait,
diff --git a/std/hash_map.zig b/std/hash_map.zig
index bdd6cc7519..431fbb35ab 100644
--- a/std/hash_map.zig
+++ b/std/hash_map.zig
@@ -540,6 +540,7 @@ pub fn autoHash(key: var, comptime rng: *std.rand.Random, comptime HashInt: type
.Undefined,
.ArgTuple,
.Frame,
+ .AnyFrame,
=> @compileError("cannot hash this type"),
.Void,
diff --git a/std/testing.zig b/std/testing.zig
index 3c4772cf37..7f347b0c24 100644
--- a/std/testing.zig
+++ b/std/testing.zig
@@ -30,6 +30,7 @@ pub fn expectEqual(expected: var, actual: @typeOf(expected)) void {
.ArgTuple,
.Opaque,
.Frame,
+ .AnyFrame,
=> @compileError("value of type " ++ @typeName(@typeOf(actual)) ++ " encountered"),
.Undefined,
diff --git a/std/zig/ast.zig b/std/zig/ast.zig
index 38bd94339f..475a0e4e13 100644
--- a/std/zig/ast.zig
+++ b/std/zig/ast.zig
@@ -400,7 +400,7 @@ pub const Node = struct {
VarType,
ErrorType,
FnProto,
- PromiseType,
+ AnyFrameType,
// Primary expressions
IntegerLiteral,
@@ -952,9 +952,9 @@ pub const Node = struct {
}
};
- pub const PromiseType = struct {
+ pub const AnyFrameType = struct {
base: Node,
- promise_token: TokenIndex,
+ anyframe_token: TokenIndex,
result: ?Result,
pub const Result = struct {
@@ -962,7 +962,7 @@ pub const Node = struct {
return_type: *Node,
};
- pub fn iterate(self: *PromiseType, index: usize) ?*Node {
+ pub fn iterate(self: *AnyFrameType, index: usize) ?*Node {
var i = index;
if (self.result) |result| {
@@ -973,13 +973,13 @@ pub const Node = struct {
return null;
}
- pub fn firstToken(self: *const PromiseType) TokenIndex {
- return self.promise_token;
+ pub fn firstToken(self: *const AnyFrameType) TokenIndex {
+ return self.anyframe_token;
}
- pub fn lastToken(self: *const PromiseType) TokenIndex {
+ pub fn lastToken(self: *const AnyFrameType) TokenIndex {
if (self.result) |result| return result.return_type.lastToken();
- return self.promise_token;
+ return self.anyframe_token;
}
};
diff --git a/std/zig/parse.zig b/std/zig/parse.zig
index 59acf99890..600178cdce 100644
--- a/std/zig/parse.zig
+++ b/std/zig/parse.zig
@@ -1201,7 +1201,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
/// / KEYWORD_error DOT IDENTIFIER
/// / KEYWORD_false
/// / KEYWORD_null
-/// / KEYWORD_promise
+/// / KEYWORD_anyframe
/// / KEYWORD_true
/// / KEYWORD_undefined
/// / KEYWORD_unreachable
@@ -1256,11 +1256,11 @@ fn parsePrimaryTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N
}
if (eatToken(it, .Keyword_false)) |token| return createLiteral(arena, Node.BoolLiteral, token);
if (eatToken(it, .Keyword_null)) |token| return createLiteral(arena, Node.NullLiteral, token);
- if (eatToken(it, .Keyword_promise)) |token| {
- const node = try arena.create(Node.PromiseType);
- node.* = Node.PromiseType{
- .base = Node{ .id = .PromiseType },
- .promise_token = token,
+ if (eatToken(it, .Keyword_anyframe)) |token| {
+ const node = try arena.create(Node.AnyFrameType);
+ node.* = Node.AnyFrameType{
+ .base = Node{ .id = .AnyFrameType },
+ .anyframe_token = token,
.result = null,
};
return &node.base;
@@ -2194,7 +2194,7 @@ fn parsePrefixOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
/// PrefixTypeOp
/// <- QUESTIONMARK
-/// / KEYWORD_promise MINUSRARROW
+/// / KEYWORD_anyframe MINUSRARROW
/// / ArrayTypeStart (ByteAlign / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)*
/// / PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)*
fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
@@ -2209,20 +2209,20 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
return &node.base;
}
- // TODO: Returning a PromiseType instead of PrefixOp makes casting and setting .rhs or
+ // TODO: Returning a AnyFrameType instead of PrefixOp makes casting and setting .rhs or
// .return_type more difficult for the caller (see parsePrefixOpExpr helper).
- // Consider making the PromiseType a member of PrefixOp and add a
- // PrefixOp.PromiseType variant?
- if (eatToken(it, .Keyword_promise)) |token| {
+ // Consider making the AnyFrameType a member of PrefixOp and add a
+ // PrefixOp.AnyFrameType variant?
+ if (eatToken(it, .Keyword_anyframe)) |token| {
const arrow = eatToken(it, .Arrow) orelse {
putBackToken(it, token);
return null;
};
- const node = try arena.create(Node.PromiseType);
- node.* = Node.PromiseType{
- .base = Node{ .id = .PromiseType },
- .promise_token = token,
- .result = Node.PromiseType.Result{
+ const node = try arena.create(Node.AnyFrameType);
+ node.* = Node.AnyFrameType{
+ .base = Node{ .id = .AnyFrameType },
+ .anyframe_token = token,
+ .result = Node.AnyFrameType.Result{
.arrow_token = arrow,
.return_type = undefined, // set by caller
},
@@ -2903,8 +2903,8 @@ fn parsePrefixOpExpr(
rightmost_op = rhs;
} else break;
},
- .PromiseType => {
- const prom = rightmost_op.cast(Node.PromiseType).?;
+ .AnyFrameType => {
+ const prom = rightmost_op.cast(Node.AnyFrameType).?;
if (try opParseFn(arena, it, tree)) |rhs| {
prom.result.?.return_type = rhs;
rightmost_op = rhs;
@@ -2922,8 +2922,8 @@ fn parsePrefixOpExpr(
.InvalidToken = AstError.InvalidToken{ .token = it.index },
});
},
- .PromiseType => {
- const prom = rightmost_op.cast(Node.PromiseType).?;
+ .AnyFrameType => {
+ const prom = rightmost_op.cast(Node.AnyFrameType).?;
prom.result.?.return_type = try expectNode(arena, it, tree, childParseFn, AstError{
.InvalidToken = AstError.InvalidToken{ .token = it.index },
});
diff --git a/std/zig/parser_test.zig b/std/zig/parser_test.zig
index f6f3363bf6..28cde6de01 100644
--- a/std/zig/parser_test.zig
+++ b/std/zig/parser_test.zig
@@ -2111,12 +2111,12 @@ test "zig fmt: coroutines" {
\\ suspend;
\\ x += 1;
\\ suspend;
- \\ const p: promise->void = async simpleAsyncFn() catch unreachable;
+ \\ const p: anyframe->void = async simpleAsyncFn() catch unreachable;
\\ await p;
\\}
\\
\\test "coroutine suspend, resume, cancel" {
- \\ const p: promise = try async testAsyncSeq();
+ \\ const p: anyframe = try async testAsyncSeq();
\\ resume p;
\\ cancel p;
\\}
diff --git a/std/zig/render.zig b/std/zig/render.zig
index b85c11c6ac..c6bb51267d 100644
--- a/std/zig/render.zig
+++ b/std/zig/render.zig
@@ -1205,15 +1205,15 @@ fn renderExpression(
}
},
- ast.Node.Id.PromiseType => {
- const promise_type = @fieldParentPtr(ast.Node.PromiseType, "base", base);
+ ast.Node.Id.AnyFrameType => {
+ const anyframe_type = @fieldParentPtr(ast.Node.AnyFrameType, "base", base);
- if (promise_type.result) |result| {
- try renderToken(tree, stream, promise_type.promise_token, indent, start_col, Space.None); // promise
+ if (anyframe_type.result) |result| {
+ try renderToken(tree, stream, anyframe_type.anyframe_token, indent, start_col, Space.None); // anyframe
try renderToken(tree, stream, result.arrow_token, indent, start_col, Space.None); // ->
return renderExpression(allocator, stream, tree, indent, start_col, result.return_type, space);
} else {
- return renderToken(tree, stream, promise_type.promise_token, indent, start_col, space); // promise
+ return renderToken(tree, stream, anyframe_type.anyframe_token, indent, start_col, space); // anyframe
}
},
diff --git a/std/zig/tokenizer.zig b/std/zig/tokenizer.zig
index 4539e1e5b2..9de20c39f2 100644
--- a/std/zig/tokenizer.zig
+++ b/std/zig/tokenizer.zig
@@ -15,6 +15,7 @@ pub const Token = struct {
Keyword{ .bytes = "align", .id = Id.Keyword_align },
Keyword{ .bytes = "allowzero", .id = Id.Keyword_allowzero },
Keyword{ .bytes = "and", .id = Id.Keyword_and },
+ Keyword{ .bytes = "anyframe", .id = Id.Keyword_anyframe },
Keyword{ .bytes = "asm", .id = Id.Keyword_asm },
Keyword{ .bytes = "async", .id = Id.Keyword_async },
Keyword{ .bytes = "await", .id = Id.Keyword_await },
@@ -42,7 +43,6 @@ pub const Token = struct {
Keyword{ .bytes = "or", .id = Id.Keyword_or },
Keyword{ .bytes = "orelse", .id = Id.Keyword_orelse },
Keyword{ .bytes = "packed", .id = Id.Keyword_packed },
- Keyword{ .bytes = "promise", .id = Id.Keyword_promise },
Keyword{ .bytes = "pub", .id = Id.Keyword_pub },
Keyword{ .bytes = "resume", .id = Id.Keyword_resume },
Keyword{ .bytes = "return", .id = Id.Keyword_return },
@@ -174,7 +174,7 @@ pub const Token = struct {
Keyword_or,
Keyword_orelse,
Keyword_packed,
- Keyword_promise,
+ Keyword_anyframe,
Keyword_pub,
Keyword_resume,
Keyword_return,
diff --git a/test/stage1/behavior/type_info.zig b/test/stage1/behavior/type_info.zig
index 6a51015124..b86ba27c13 100644
--- a/test/stage1/behavior/type_info.zig
+++ b/test/stage1/behavior/type_info.zig
@@ -177,11 +177,11 @@ fn testUnion() void {
expect(TypeId(typeinfo_info) == TypeId.Union);
expect(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);
expect(typeinfo_info.Union.tag_type.? == TypeId);
- expect(typeinfo_info.Union.fields.len == 25);
+ expect(typeinfo_info.Union.fields.len == 26);
expect(typeinfo_info.Union.fields[4].enum_field != null);
expect(typeinfo_info.Union.fields[4].enum_field.?.value == 4);
expect(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int));
- expect(typeinfo_info.Union.decls.len == 20);
+ expect(typeinfo_info.Union.decls.len == 21);
const TestNoTagUnion = union {
Foo: void,
@@ -280,6 +280,25 @@ fn testVector() void {
expect(vec_info.Vector.child == i32);
}
+test "type info: anyframe and anyframe->T" {
+ testAnyFrame();
+ comptime testAnyFrame();
+}
+
+fn testAnyFrame() void {
+ {
+ const anyframe_info = @typeInfo(anyframe->i32);
+ expect(TypeId(anyframe_info) == .AnyFrame);
+ expect(anyframe_info.AnyFrame.child.? == i32);
+ }
+
+ {
+ const anyframe_info = @typeInfo(anyframe);
+ expect(TypeId(anyframe_info) == .AnyFrame);
+ expect(anyframe_info.AnyFrame.child == null);
+ }
+}
+
test "type info: optional field unwrapping" {
const Struct = struct {
cdOffset: u32,
--
cgit v1.2.3
From 13b5a4bf8ca65c569e6b28ca0e41d101d12d0ff1 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 15 Aug 2019 14:05:12 -0400
Subject: remove `cancel`
---
doc/docgen.zig | 1 -
doc/langref.html.in | 14 +-
src-self-hosted/main.zig | 3 -
src/all_types.hpp | 33 +--
src/analyze.cpp | 53 +++--
src/analyze.hpp | 2 +-
src/ast_render.cpp | 8 -
src/codegen.cpp | 412 +++++++++++++++-----------------------
src/ir.cpp | 230 +++------------------
src/ir_print.cpp | 24 ---
src/parser.cpp | 12 --
src/tokenizer.cpp | 2 -
src/tokenizer.hpp | 1 -
std/event/fs.zig | 2 +-
std/event/future.zig | 2 +-
std/event/group.zig | 20 +-
std/event/net.zig | 8 +-
std/zig/parse.zig | 15 --
std/zig/parser_test.zig | 4 +-
std/zig/tokenizer.zig | 2 -
test/compile_errors.zig | 8 +-
test/stage1/behavior.zig | 1 -
test/stage1/behavior/async_fn.zig | 90 ++-------
test/stage1/behavior/cancel.zig | 115 -----------
24 files changed, 256 insertions(+), 806 deletions(-)
delete mode 100644 test/stage1/behavior/cancel.zig
(limited to 'src/parser.cpp')
diff --git a/doc/docgen.zig b/doc/docgen.zig
index 92764d7642..458b97d2c0 100644
--- a/doc/docgen.zig
+++ b/doc/docgen.zig
@@ -750,7 +750,6 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
.Keyword_async,
.Keyword_await,
.Keyword_break,
- .Keyword_cancel,
.Keyword_catch,
.Keyword_comptime,
.Keyword_const,
diff --git a/doc/langref.html.in b/doc/langref.html.in
index 23e4dd194e..0f964373c5 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -5971,7 +5971,7 @@ test "global assembly" {
{#header_open|Async Functions#}
An async function is a function whose callsite is split into an {#syntax#}async{#endsyntax#} initiation,
- followed by an {#syntax#}await{#endsyntax#} completion. They can also be canceled.
+ followed by an {#syntax#}await{#endsyntax#} completion.
When you call a function, it creates a stack frame,
@@ -6013,11 +6013,11 @@ test "global assembly" {
The result of an async function call is a {#syntax#}promise->T{#endsyntax#} type, where {#syntax#}T{#endsyntax#}
is the return type of the async function. Once a promise has been created, it must be
- consumed, either with {#syntax#}cancel{#endsyntax#} or {#syntax#}await{#endsyntax#}:
+ consumed with {#syntax#}await{#endsyntax#}:
Async functions start executing when created, so in the following example, the entire
- async function completes before it is canceled:
+ TODO
{#code_begin|test#}
const std = @import("std");
@@ -6048,7 +6048,7 @@ fn simpleAsyncFn() void {
When an async function suspends itself, it must be sure that it will be
- resumed or canceled somehow, for example by registering its promise handle
+ resumed somehow, for example by registering its promise handle
in an event loop. Use a suspend capture block to gain access to the
promise (TODO this is outdated):
@@ -6134,7 +6134,7 @@ async fn testResumeFromSuspend(my_result: *i32) void {
resumes the awaiter.
- A promise handle must be consumed exactly once after it is created, either by {#syntax#}cancel{#endsyntax#} or {#syntax#}await{#endsyntax#}.
+ A frame handle must be consumed exactly once after it is created with {#syntax#}await{#endsyntax#}.
{#syntax#}await{#endsyntax#} counts as a suspend point, and therefore at every {#syntax#}await{#endsyntax#},
@@ -9764,7 +9764,6 @@ PrimaryExpr
<- AsmExpr
/ IfExpr
/ KEYWORD_break BreakLabel? Expr?
- / KEYWORD_cancel Expr
/ KEYWORD_comptime Expr
/ KEYWORD_continue BreakLabel?
/ KEYWORD_resume Expr
@@ -10120,7 +10119,6 @@ KEYWORD_asm <- 'asm' end_of_word
KEYWORD_async <- 'async' end_of_word
KEYWORD_await <- 'await' end_of_word
KEYWORD_break <- 'break' end_of_word
-KEYWORD_cancel <- 'cancel' end_of_word
KEYWORD_catch <- 'catch' end_of_word
KEYWORD_comptime <- 'comptime' end_of_word
KEYWORD_const <- 'const' end_of_word
@@ -10165,7 +10163,7 @@ KEYWORD_volatile <- 'volatile' end_of_word
KEYWORD_while <- 'while' end_of_word
keyword <- KEYWORD_align / KEYWORD_and / KEYWORD_allowzero / KEYWORD_asm
- / KEYWORD_async / KEYWORD_await / KEYWORD_break / KEYWORD_cancel
+ / KEYWORD_async / KEYWORD_await / KEYWORD_break
/ KEYWORD_catch / KEYWORD_comptime / KEYWORD_const / KEYWORD_continue
/ KEYWORD_defer / KEYWORD_else / KEYWORD_enum / KEYWORD_errdefer
/ KEYWORD_error / KEYWORD_export / KEYWORD_extern / KEYWORD_false
diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig
index bc5d078950..5136b32735 100644
--- a/src-self-hosted/main.zig
+++ b/src-self-hosted/main.zig
@@ -467,7 +467,6 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co
comp.start();
// TODO const process_build_events_handle = try async processBuildEvents(comp, color);
- defer cancel process_build_events_handle;
loop.run();
}
@@ -579,7 +578,6 @@ fn cmdLibC(allocator: *Allocator, args: []const []const u8) !void {
defer zig_compiler.deinit();
// TODO const handle = try async findLibCAsync(&zig_compiler);
- defer cancel handle;
loop.run();
}
@@ -669,7 +667,6 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {
// TODO &flags,
// TODO color,
// TODO );
- defer cancel main_handle;
loop.run();
return result;
}
diff --git a/src/all_types.hpp b/src/all_types.hpp
index 22e38b9f0c..f1c699ba10 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -476,7 +476,6 @@ enum NodeType {
NodeTypeIfErrorExpr,
NodeTypeIfOptional,
NodeTypeErrorSetDecl,
- NodeTypeCancel,
NodeTypeResume,
NodeTypeAwaitExpr,
NodeTypeSuspend,
@@ -911,10 +910,6 @@ struct AstNodeBreakExpr {
AstNode *expr; // may be null
};
-struct AstNodeCancelExpr {
- AstNode *expr;
-};
-
struct AstNodeResumeExpr {
AstNode *expr;
};
@@ -1003,7 +998,6 @@ struct AstNode {
AstNodeInferredArrayType inferred_array_type;
AstNodeErrorType error_type;
AstNodeErrorSetDecl err_set_decl;
- AstNodeCancelExpr cancel_expr;
AstNodeResumeExpr resume_expr;
AstNodeAwaitExpr await_expr;
AstNodeSuspend suspend;
@@ -1561,7 +1555,6 @@ enum PanicMsgId {
PanicMsgIdBadAwait,
PanicMsgIdBadReturn,
PanicMsgIdResumedAnAwaitingFn,
- PanicMsgIdResumedACancelingFn,
PanicMsgIdFrameTooSmall,
PanicMsgIdResumedFnPendingAwait,
@@ -1729,8 +1722,6 @@ struct CodeGen {
LLVMValueRef cur_async_switch_instr;
LLVMValueRef cur_async_resume_index_ptr;
LLVMValueRef cur_async_awaiter_ptr;
- LLVMValueRef cur_async_prev_val;
- LLVMValueRef cur_async_prev_val_field_ptr;
LLVMBasicBlockRef cur_preamble_llvm_block;
size_t cur_resume_block_count;
LLVMValueRef cur_err_ret_trace_val_arg;
@@ -1822,7 +1813,6 @@ struct CodeGen {
ZigType *align_amt_type;
ZigType *stack_trace_type;
- ZigType *ptr_to_stack_trace_type;
ZigType *err_tag_type;
ZigType *test_fn_type;
@@ -1892,7 +1882,6 @@ struct CodeGen {
bool system_linker_hack;
bool reported_bad_link_libc_error;
bool is_dynamic; // shared library rather than static library. dynamic musl rather than static musl.
- bool cur_is_after_return;
//////////////////////////// Participates in Input Parameter Cache Hash
/////// Note: there is a separate cache hash for builtin.zig, when adding fields,
@@ -2235,7 +2224,6 @@ enum IrInstructionId {
IrInstructionIdCallGen,
IrInstructionIdConst,
IrInstructionIdReturn,
- IrInstructionIdReturnBegin,
IrInstructionIdCast,
IrInstructionIdResizeSlice,
IrInstructionIdContainerInitList,
@@ -2345,7 +2333,6 @@ enum IrInstructionId {
IrInstructionIdExport,
IrInstructionIdErrorReturnTrace,
IrInstructionIdErrorUnion,
- IrInstructionIdCancel,
IrInstructionIdAtomicRmw,
IrInstructionIdAtomicLoad,
IrInstructionIdSaveErrRetAddr,
@@ -2370,7 +2357,6 @@ enum IrInstructionId {
IrInstructionIdAwaitSrc,
IrInstructionIdAwaitGen,
IrInstructionIdResume,
- IrInstructionIdTestCancelRequested,
IrInstructionIdSpillBegin,
IrInstructionIdSpillEnd,
};
@@ -2649,12 +2635,6 @@ struct IrInstructionReturn {
IrInstruction *operand;
};
-struct IrInstructionReturnBegin {
- IrInstruction base;
-
- IrInstruction *operand;
-};
-
enum CastOp {
CastOpNoCast, // signifies the function call expression is not a cast
CastOpNoop, // fn call expr is a cast, but does nothing
@@ -3440,12 +3420,6 @@ struct IrInstructionErrorUnion {
IrInstruction *payload;
};
-struct IrInstructionCancel {
- IrInstruction base;
-
- IrInstruction *frame;
-};
-
struct IrInstructionAtomicRmw {
IrInstruction base;
@@ -3647,10 +3621,6 @@ struct IrInstructionResume {
IrInstruction *frame;
};
-struct IrInstructionTestCancelRequested {
- IrInstruction base;
-};
-
enum SpillId {
SpillIdInvalid,
SpillIdRetErrCode,
@@ -3756,8 +3726,7 @@ static const size_t err_union_err_index = 1;
static const size_t frame_fn_ptr_index = 0;
static const size_t frame_resume_index = 1;
static const size_t frame_awaiter_index = 2;
-static const size_t frame_prev_val_index = 3;
-static const size_t frame_ret_start = 4;
+static const size_t frame_ret_start = 3;
// TODO https://github.com/ziglang/zig/issues/3056
// We require this to be a power of 2 so that we can use shifting rather than
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 1b6de6e7df..fc42abaf26 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -828,17 +828,15 @@ bool calling_convention_allows_zig_types(CallingConvention cc) {
zig_unreachable();
}
-ZigType *get_ptr_to_stack_trace_type(CodeGen *g) {
+ZigType *get_stack_trace_type(CodeGen *g) {
if (g->stack_trace_type == nullptr) {
ConstExprValue *stack_trace_type_val = get_builtin_value(g, "StackTrace");
assert(stack_trace_type_val->type->id == ZigTypeIdMetaType);
g->stack_trace_type = stack_trace_type_val->data.x_type;
assertNoError(type_resolve(g, g->stack_trace_type, ResolveStatusZeroBitsKnown));
-
- g->ptr_to_stack_trace_type = get_pointer_to_type(g, g->stack_trace_type, false);
}
- return g->ptr_to_stack_trace_type;
+ return g->stack_trace_type;
}
bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id) {
@@ -3035,7 +3033,6 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
case NodeTypeIfErrorExpr:
case NodeTypeIfOptional:
case NodeTypeErrorSetDecl:
- case NodeTypeCancel:
case NodeTypeResume:
case NodeTypeAwaitExpr:
case NodeTypeSuspend:
@@ -3822,11 +3819,9 @@ static void add_async_error_notes(CodeGen *g, ErrorMsg *msg, ZigFn *fn) {
} else if (fn->inferred_async_node->type == NodeTypeAwaitExpr) {
add_error_note(g, msg, fn->inferred_async_node,
buf_sprintf("await is a suspend point"));
- } else if (fn->inferred_async_node->type == NodeTypeCancel) {
- add_error_note(g, msg, fn->inferred_async_node,
- buf_sprintf("cancel is a suspend point"));
} else {
- zig_unreachable();
+ add_error_note(g, msg, fn->inferred_async_node,
+ buf_sprintf("suspends here"));
}
}
@@ -5231,12 +5226,21 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
fields.append({"@fn_ptr", g->builtin_types.entry_usize, 0});
fields.append({"@resume_index", g->builtin_types.entry_usize, 0});
fields.append({"@awaiter", g->builtin_types.entry_usize, 0});
- fields.append({"@prev_val", g->builtin_types.entry_usize, 0});
fields.append({"@result_ptr_callee", ptr_return_type, 0});
fields.append({"@result_ptr_awaiter", ptr_return_type, 0});
fields.append({"@result", fn_type_id->return_type, 0});
+ if (codegen_fn_has_err_ret_tracing_arg(g, fn_type_id->return_type)) {
+ ZigType *ptr_to_stack_trace_type = get_pointer_to_type(g, get_stack_trace_type(g), false);
+ fields.append({"@ptr_stack_trace_callee", ptr_to_stack_trace_type, 0});
+ fields.append({"@ptr_stack_trace_awaiter", ptr_to_stack_trace_type, 0});
+
+ fields.append({"@stack_trace", get_stack_trace_type(g), 0});
+ fields.append({"@instruction_addresses",
+ get_array_type(g, g->builtin_types.entry_usize, stack_trace_ptr_count), 0});
+ }
+
frame_type->data.frame.locals_struct = get_struct_type(g, buf_ptr(&frame_type->name),
fields.items, fields.length, target_fn_align(g->zig_target));
frame_type->abi_size = frame_type->data.frame.locals_struct->abi_size;
@@ -5311,14 +5315,15 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
fields.append({"@fn_ptr", fn_type, 0});
fields.append({"@resume_index", g->builtin_types.entry_usize, 0});
fields.append({"@awaiter", g->builtin_types.entry_usize, 0});
- fields.append({"@prev_val", g->builtin_types.entry_usize, 0});
fields.append({"@result_ptr_callee", ptr_return_type, 0});
fields.append({"@result_ptr_awaiter", ptr_return_type, 0});
fields.append({"@result", fn_type_id->return_type, 0});
if (codegen_fn_has_err_ret_tracing_arg(g, fn_type_id->return_type)) {
- fields.append({"@ptr_stack_trace", get_ptr_to_stack_trace_type(g), 0});
+ ZigType *ptr_stack_trace_type = get_pointer_to_type(g, get_stack_trace_type(g), false);
+ fields.append({"@ptr_stack_trace_callee", ptr_stack_trace_type, 0});
+ fields.append({"@ptr_stack_trace_awaiter", ptr_stack_trace_type, 0});
}
for (size_t arg_i = 0; arg_i < fn_type_id->param_count; arg_i += 1) {
@@ -5337,9 +5342,7 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
}
if (codegen_fn_has_err_ret_tracing_stack(g, fn, true)) {
- (void)get_ptr_to_stack_trace_type(g); // populate g->stack_trace_type
-
- fields.append({"@stack_trace", g->stack_trace_type, 0});
+ fields.append({"@stack_trace", get_stack_trace_type(g), 0});
fields.append({"@instruction_addresses",
get_array_type(g, g->builtin_types.entry_usize, stack_trace_ptr_count), 0});
}
@@ -7553,7 +7556,7 @@ static void resolve_llvm_types_fn_type(CodeGen *g, ZigType *fn_type) {
fn_type->data.fn.gen_return_type = gen_return_type;
if (prefix_arg_error_return_trace && !is_async) {
- ZigType *gen_type = get_ptr_to_stack_trace_type(g);
+ ZigType *gen_type = get_pointer_to_type(g, get_stack_trace_type(g), false);
gen_param_types.append(get_llvm_type(g, gen_type));
param_di_types.append(get_llvm_di_type(g, gen_type));
}
@@ -7727,7 +7730,6 @@ static void resolve_llvm_types_any_frame(CodeGen *g, ZigType *any_frame_type, Re
field_types.append(ptr_fn_llvm_type); // fn_ptr
field_types.append(usize_type_ref); // resume_index
field_types.append(usize_type_ref); // awaiter
- field_types.append(usize_type_ref); // prev_val
bool have_result_type = result_type != nullptr && type_has_bits(result_type);
if (have_result_type) {
@@ -7735,7 +7737,9 @@ static void resolve_llvm_types_any_frame(CodeGen *g, ZigType *any_frame_type, Re
field_types.append(get_llvm_type(g, ptr_result_type)); // result_ptr_awaiter
field_types.append(get_llvm_type(g, result_type)); // result
if (codegen_fn_has_err_ret_tracing_arg(g, result_type)) {
- field_types.append(get_llvm_type(g, get_ptr_to_stack_trace_type(g))); // ptr_stack_trace
+ ZigType *ptr_stack_trace = get_pointer_to_type(g, get_stack_trace_type(g), false);
+ field_types.append(get_llvm_type(g, ptr_stack_trace)); // ptr_stack_trace_callee
+ field_types.append(get_llvm_type(g, ptr_stack_trace)); // ptr_stack_trace_awaiter
}
}
LLVMStructSetBody(frame_header_type, field_types.items, field_types.length, false);
@@ -7792,14 +7796,23 @@ static void resolve_llvm_types_any_frame(CodeGen *g, ZigType *any_frame_type, Re
ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, result_type)));
if (codegen_fn_has_err_ret_tracing_arg(g, result_type)) {
+ ZigType *ptr_stack_trace = get_pointer_to_type(g, get_stack_trace_type(g), false);
+ di_element_types.append(
+ ZigLLVMCreateDebugMemberType(g->dbuilder,
+ ZigLLVMTypeToScope(any_frame_type->llvm_di_type), "ptr_stack_trace_callee",
+ di_file, line,
+ 8*LLVMABISizeOfType(g->target_data_ref, field_types.at(di_element_types.length)),
+ 8*LLVMABIAlignmentOfType(g->target_data_ref, field_types.at(di_element_types.length)),
+ 8*LLVMOffsetOfElement(g->target_data_ref, frame_header_type, di_element_types.length),
+ ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, ptr_stack_trace)));
di_element_types.append(
ZigLLVMCreateDebugMemberType(g->dbuilder,
- ZigLLVMTypeToScope(any_frame_type->llvm_di_type), "ptr_stack_trace",
+ ZigLLVMTypeToScope(any_frame_type->llvm_di_type), "ptr_stack_trace_awaiter",
di_file, line,
8*LLVMABISizeOfType(g->target_data_ref, field_types.at(di_element_types.length)),
8*LLVMABIAlignmentOfType(g->target_data_ref, field_types.at(di_element_types.length)),
8*LLVMOffsetOfElement(g->target_data_ref, frame_header_type, di_element_types.length),
- ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, get_ptr_to_stack_trace_type(g))));
+ ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, ptr_stack_trace)));
}
};
diff --git a/src/analyze.hpp b/src/analyze.hpp
index e6336d3cdc..5752c74751 100644
--- a/src/analyze.hpp
+++ b/src/analyze.hpp
@@ -195,7 +195,7 @@ void add_var_export(CodeGen *g, ZigVar *fn_table_entry, Buf *symbol_name, Global
ConstExprValue *get_builtin_value(CodeGen *codegen, const char *name);
-ZigType *get_ptr_to_stack_trace_type(CodeGen *g);
+ZigType *get_stack_trace_type(CodeGen *g);
bool resolve_inferred_error_set(CodeGen *g, ZigType *err_set_type, AstNode *source_node);
ZigType *get_auto_err_set_type(CodeGen *g, ZigFn *fn_entry);
diff --git a/src/ast_render.cpp b/src/ast_render.cpp
index dd4d9cf646..334dc37b59 100644
--- a/src/ast_render.cpp
+++ b/src/ast_render.cpp
@@ -249,8 +249,6 @@ static const char *node_type_str(NodeType node_type) {
return "IfOptional";
case NodeTypeErrorSetDecl:
return "ErrorSetDecl";
- case NodeTypeCancel:
- return "Cancel";
case NodeTypeResume:
return "Resume";
case NodeTypeAwaitExpr:
@@ -1136,12 +1134,6 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
fprintf(ar->f, "}");
break;
}
- case NodeTypeCancel:
- {
- fprintf(ar->f, "cancel ");
- render_node_grouped(ar, node->data.cancel_expr.expr);
- break;
- }
case NodeTypeResume:
{
fprintf(ar->f, "resume ");
diff --git a/src/codegen.cpp b/src/codegen.cpp
index e9f323dd0d..9bf7b0287b 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -28,8 +28,6 @@ enum ResumeId {
ResumeIdManual,
ResumeIdReturn,
ResumeIdCall,
-
- ResumeIdAwaitEarlyReturn // must be last
};
static void init_darwin_native(CodeGen *g) {
@@ -317,8 +315,9 @@ static uint32_t frame_index_trace_arg(CodeGen *g, ZigType *return_type) {
// label (grep this): [fn_frame_struct_layout]
static uint32_t frame_index_arg(CodeGen *g, ZigType *return_type) {
bool have_stack_trace = codegen_fn_has_err_ret_tracing_arg(g, return_type);
- // [0] *StackTrace
- uint32_t trace_field_count = have_stack_trace ? 1 : 0;
+ // [0] *StackTrace (callee's)
+ // [1] *StackTrace (awaiter's)
+ uint32_t trace_field_count = have_stack_trace ? 2 : 0;
return frame_index_trace_arg(g, return_type) + trace_field_count;
}
@@ -916,8 +915,6 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) {
return buf_create_from_str("async function returned twice");
case PanicMsgIdResumedAnAwaitingFn:
return buf_create_from_str("awaiting function resumed");
- case PanicMsgIdResumedACancelingFn:
- return buf_create_from_str("canceling function resumed");
case PanicMsgIdFrameTooSmall:
return buf_create_from_str("frame too small");
case PanicMsgIdResumedFnPendingAwait:
@@ -946,13 +943,16 @@ static LLVMValueRef get_panic_msg_ptr_val(CodeGen *g, PanicMsgId msg_id) {
return LLVMConstBitCast(val->global_refs->llvm_global, LLVMPointerType(get_llvm_type(g, str_type), 0));
}
+static ZigType *ptr_to_stack_trace_type(CodeGen *g) {
+ return get_pointer_to_type(g, get_stack_trace_type(g), false);
+}
+
static void gen_panic(CodeGen *g, LLVMValueRef msg_arg, LLVMValueRef stack_trace_arg) {
assert(g->panic_fn != nullptr);
LLVMValueRef fn_val = fn_llvm_value(g, g->panic_fn);
LLVMCallConv llvm_cc = get_llvm_cc(g, g->panic_fn->type_entry->data.fn.fn_type_id.cc);
if (stack_trace_arg == nullptr) {
- ZigType *ptr_to_stack_trace_type = get_ptr_to_stack_trace_type(g);
- stack_trace_arg = LLVMConstNull(get_llvm_type(g, ptr_to_stack_trace_type));
+ stack_trace_arg = LLVMConstNull(get_llvm_type(g, ptr_to_stack_trace_type(g)));
}
LLVMValueRef args[] = {
msg_arg,
@@ -1046,7 +1046,7 @@ static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) {
return g->add_error_return_trace_addr_fn_val;
LLVMTypeRef arg_types[] = {
- get_llvm_type(g, get_ptr_to_stack_trace_type(g)),
+ get_llvm_type(g, ptr_to_stack_trace_type(g)),
g->builtin_types.entry_usize->llvm_type,
};
LLVMTypeRef fn_type_ref = LLVMFunctionType(LLVMVoidType(), arg_types, 2, false);
@@ -1127,7 +1127,7 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) {
LLVMTypeRef arg_types[] = {
// error return trace pointer
- get_llvm_type(g, get_ptr_to_stack_trace_type(g)),
+ get_llvm_type(g, ptr_to_stack_trace_type(g)),
};
LLVMTypeRef fn_type_ref = LLVMFunctionType(LLVMVoidType(), arg_types, 1, false);
@@ -1205,7 +1205,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
LLVMTypeRef fn_type_ref;
if (g->have_err_ret_tracing) {
LLVMTypeRef arg_types[] = {
- get_llvm_type(g, g->ptr_to_stack_trace_type),
+ get_llvm_type(g, get_pointer_to_type(g, get_stack_trace_type(g), false)),
get_llvm_type(g, g->err_tag_type),
};
fn_type_ref = LLVMFunctionType(LLVMVoidType(), arg_types, 2, false);
@@ -1321,14 +1321,7 @@ static LLVMValueRef get_cur_err_ret_trace_val(CodeGen *g, Scope *scope) {
if (g->cur_err_ret_trace_val_stack != nullptr) {
return g->cur_err_ret_trace_val_stack;
}
- if (g->cur_err_ret_trace_val_arg != nullptr) {
- if (fn_is_async(g->cur_fn)) {
- return LLVMBuildLoad(g->builder, g->cur_err_ret_trace_val_arg, "");
- } else {
- return g->cur_err_ret_trace_val_arg;
- }
- }
- return nullptr;
+ return g->cur_err_ret_trace_val_arg;
}
static void gen_safety_crash_for_err(CodeGen *g, LLVMValueRef err_val, Scope *scope) {
@@ -1337,8 +1330,7 @@ static void gen_safety_crash_for_err(CodeGen *g, LLVMValueRef err_val, Scope *sc
if (g->have_err_ret_tracing) {
LLVMValueRef err_ret_trace_val = get_cur_err_ret_trace_val(g, scope);
if (err_ret_trace_val == nullptr) {
- ZigType *ptr_to_stack_trace_type = get_ptr_to_stack_trace_type(g);
- err_ret_trace_val = LLVMConstNull(get_llvm_type(g, ptr_to_stack_trace_type));
+ err_ret_trace_val = LLVMConstNull(get_llvm_type(g, ptr_to_stack_trace_type(g)));
}
LLVMValueRef args[] = {
err_ret_trace_val,
@@ -2044,8 +2036,8 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
assert(g->stack_trace_type != nullptr);
LLVMTypeRef param_types[] = {
- get_llvm_type(g, get_ptr_to_stack_trace_type(g)),
- get_llvm_type(g, get_ptr_to_stack_trace_type(g)),
+ get_llvm_type(g, ptr_to_stack_trace_type(g)),
+ get_llvm_type(g, ptr_to_stack_trace_type(g)),
};
LLVMTypeRef fn_type_ref = LLVMFunctionType(LLVMVoidType(), param_types, 2, false);
@@ -2058,7 +2050,6 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
addLLVMArgAttr(fn_val, (unsigned)0, "noalias");
addLLVMArgAttr(fn_val, (unsigned)0, "writeonly");
- addLLVMArgAttr(fn_val, (unsigned)1, "nonnull");
addLLVMArgAttr(fn_val, (unsigned)1, "noalias");
addLLVMArgAttr(fn_val, (unsigned)1, "readonly");
if (g->build_mode == BuildModeDebug) {
@@ -2075,7 +2066,7 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
LLVMPositionBuilderAtEnd(g->builder, entry_block);
ZigLLVMClearCurrentDebugLocation(g->builder);
- // if (dest_stack_trace == null) return;
+ // if (dest_stack_trace == null or src_stack_trace == null) return;
// var frame_index: usize = undefined;
// var frames_left: usize = undefined;
// if (src_stack_trace.index < src_stack_trace.instruction_addresses.len) {
@@ -2093,7 +2084,7 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
// frame_index = (frame_index + 1) % src_stack_trace.instruction_addresses.len;
// }
LLVMBasicBlockRef return_block = LLVMAppendBasicBlock(fn_val, "Return");
- LLVMBasicBlockRef dest_non_null_block = LLVMAppendBasicBlock(fn_val, "DestNonNull");
+ LLVMBasicBlockRef non_null_block = LLVMAppendBasicBlock(fn_val, "NonNull");
LLVMValueRef frame_index_ptr = LLVMBuildAlloca(g->builder, g->builtin_types.entry_usize->llvm_type, "frame_index");
LLVMValueRef frames_left_ptr = LLVMBuildAlloca(g->builder, g->builtin_types.entry_usize->llvm_type, "frames_left");
@@ -2103,9 +2094,12 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
LLVMValueRef null_dest_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, dest_stack_trace_ptr,
LLVMConstNull(LLVMTypeOf(dest_stack_trace_ptr)), "");
- LLVMBuildCondBr(g->builder, null_dest_bit, return_block, dest_non_null_block);
+ LLVMValueRef null_src_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, src_stack_trace_ptr,
+ LLVMConstNull(LLVMTypeOf(src_stack_trace_ptr)), "");
+ LLVMValueRef null_bit = LLVMBuildOr(g->builder, null_dest_bit, null_src_bit, "");
+ LLVMBuildCondBr(g->builder, null_bit, return_block, non_null_block);
- LLVMPositionBuilderAtEnd(g->builder, dest_non_null_block);
+ LLVMPositionBuilderAtEnd(g->builder, non_null_block);
size_t src_index_field_index = g->stack_trace_type->data.structure.fields[0].gen_index;
size_t src_addresses_field_index = g->stack_trace_type->data.structure.fields[1].gen_index;
LLVMValueRef src_index_field_ptr = LLVMBuildStructGEP(g->builder, src_stack_trace_ptr,
@@ -2183,13 +2177,11 @@ static LLVMValueRef ir_render_save_err_ret_addr(CodeGen *g, IrExecutable *execut
ZigLLVMBuildCall(g->builder, return_err_fn, &my_err_trace_val, 1,
get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_FnInlineAuto, "");
- if (fn_is_async(g->cur_fn) && g->cur_fn->calls_or_awaits_errorable_fn &&
- codegen_fn_has_err_ret_tracing_arg(g, g->cur_fn->type_entry->data.fn.fn_type_id.return_type))
- {
- LLVMValueRef dest_trace_ptr = LLVMBuildLoad(g->builder, g->cur_err_ret_trace_val_arg, "");
- LLVMValueRef args[] = { dest_trace_ptr, my_err_trace_val };
- ZigLLVMBuildCall(g->builder, get_merge_err_ret_traces_fn_val(g), args, 2,
- get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_FnInlineAuto, "");
+ ZigType *ret_type = g->cur_fn->type_entry->data.fn.fn_type_id.return_type;
+ if (fn_is_async(g->cur_fn) && codegen_fn_has_err_ret_tracing_arg(g, ret_type)) {
+ LLVMValueRef trace_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr,
+ frame_index_trace_arg(g, ret_type), "");
+ LLVMBuildStore(g->builder, my_err_trace_val, trace_ptr_ptr);
}
return nullptr;
@@ -2201,16 +2193,9 @@ static void gen_assert_resume_id(CodeGen *g, IrInstruction *source_instr, Resume
LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
LLVMBasicBlockRef bad_resume_block = LLVMAppendBasicBlock(g->cur_fn_val, "BadResume");
if (end_bb == nullptr) end_bb = LLVMAppendBasicBlock(g->cur_fn_val, "OkResume");
- LLVMValueRef ok_bit;
- if (resume_id == ResumeIdAwaitEarlyReturn) {
- LLVMValueRef last_value = LLVMConstSub(LLVMConstAllOnes(usize_type_ref),
- LLVMConstInt(usize_type_ref, ResumeIdAwaitEarlyReturn, false));
- ok_bit = LLVMBuildICmp(g->builder, LLVMIntULT, LLVMGetParam(g->cur_fn_val, 1), last_value, "");
- } else {
- LLVMValueRef expected_value = LLVMConstSub(LLVMConstAllOnes(usize_type_ref),
- LLVMConstInt(usize_type_ref, resume_id, false));
- ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, LLVMGetParam(g->cur_fn_val, 1), expected_value, "");
- }
+ LLVMValueRef expected_value = LLVMConstSub(LLVMConstAllOnes(usize_type_ref),
+ LLVMConstInt(usize_type_ref, resume_id, false));
+ LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, LLVMGetParam(g->cur_fn_val, 1), expected_value, "");
LLVMBuildCondBr(g->builder, ok_bit, end_bb, bad_resume_block);
LLVMPositionBuilderAtEnd(g->builder, bad_resume_block);
@@ -2219,36 +2204,19 @@ static void gen_assert_resume_id(CodeGen *g, IrInstruction *source_instr, Resume
LLVMPositionBuilderAtEnd(g->builder, end_bb);
}
-static LLVMValueRef gen_resume(CodeGen *g, LLVMValueRef fn_val, LLVMValueRef target_frame_ptr,
- ResumeId resume_id, LLVMValueRef arg_val)
-{
+static LLVMValueRef gen_resume(CodeGen *g, LLVMValueRef fn_val, LLVMValueRef target_frame_ptr, ResumeId resume_id) {
LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
if (fn_val == nullptr) {
LLVMValueRef fn_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, frame_fn_ptr_index, "");
fn_val = LLVMBuildLoad(g->builder, fn_ptr_ptr, "");
}
- if (arg_val == nullptr) {
- arg_val = LLVMBuildSub(g->builder, LLVMConstAllOnes(usize_type_ref),
- LLVMConstInt(usize_type_ref, resume_id, false), "");
- } else {
- assert(resume_id == ResumeIdAwaitEarlyReturn);
- }
+ LLVMValueRef arg_val = LLVMBuildSub(g->builder, LLVMConstAllOnes(usize_type_ref),
+ LLVMConstInt(usize_type_ref, resume_id, false), "");
LLVMValueRef args[] = {target_frame_ptr, arg_val};
return ZigLLVMBuildCall(g->builder, fn_val, args, 2, LLVMFastCallConv, ZigLLVM_FnInlineAuto, "");
}
-static LLVMValueRef get_cur_async_prev_val(CodeGen *g) {
- if (g->cur_async_prev_val != nullptr) {
- return g->cur_async_prev_val;
- }
- g->cur_async_prev_val = LLVMBuildLoad(g->builder, g->cur_async_prev_val_field_ptr, "");
- return g->cur_async_prev_val;
-}
-
static LLVMBasicBlockRef gen_suspend_begin(CodeGen *g, const char *name_hint) {
- // This becomes invalid when a suspend happens.
- g->cur_async_prev_val = nullptr;
-
LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
LLVMBasicBlockRef resume_bb = LLVMAppendBasicBlock(g->cur_fn_val, name_hint);
size_t new_block_index = g->cur_resume_block_count;
@@ -2259,6 +2227,10 @@ static LLVMBasicBlockRef gen_suspend_begin(CodeGen *g, const char *name_hint) {
return resume_bb;
}
+static void set_tail_call_if_appropriate(CodeGen *g, LLVMValueRef call_inst) {
+ LLVMSetTailCall(call_inst, true);
+}
+
static LLVMValueRef gen_maybe_atomic_op(CodeGen *g, LLVMAtomicRMWBinOp op, LLVMValueRef ptr, LLVMValueRef val,
LLVMAtomicOrdering order)
{
@@ -2282,32 +2254,32 @@ static LLVMValueRef gen_maybe_atomic_op(CodeGen *g, LLVMAtomicRMWBinOp op, LLVMV
}
}
-static LLVMValueRef ir_render_return_begin(CodeGen *g, IrExecutable *executable,
- IrInstructionReturnBegin *instruction)
-{
+static void gen_async_return(CodeGen *g, IrInstructionReturn *instruction) {
+ LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
+
ZigType *operand_type = (instruction->operand != nullptr) ? instruction->operand->value.type : nullptr;
bool operand_has_bits = (operand_type != nullptr) && type_has_bits(operand_type);
- if (!fn_is_async(g->cur_fn)) {
- return operand_has_bits ? ir_llvm_value(g, instruction->operand) : nullptr;
- }
+ ZigType *ret_type = g->cur_fn->type_entry->data.fn.fn_type_id.return_type;
+ bool ret_type_has_bits = type_has_bits(ret_type);
- LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
if (operand_has_bits && instruction->operand != nullptr) {
- ZigType *ret_type = g->cur_fn->type_entry->data.fn.fn_type_id.return_type;
bool need_store = instruction->operand->value.special != ConstValSpecialRuntime || !handle_is_ptr(ret_type);
if (need_store) {
- // It didn't get written to the result ptr. We do that now so that we do not have to spill
- // the return operand.
+ // It didn't get written to the result ptr. We do that now.
ZigType *ret_ptr_type = get_pointer_to_type(g, ret_type, true);
gen_assign_raw(g, g->cur_ret_ptr, ret_ptr_type, ir_llvm_value(g, instruction->operand));
}
}
- // Prepare to be suspended. We might end up not having to suspend though.
- LLVMBasicBlockRef resume_bb = gen_suspend_begin(g, "ReturnResume");
+ // Whether we tail resume the awaiter, or do an early return, we are done and will not be resumed.
+ if (ir_want_runtime_safety(g, &instruction->base)) {
+ LLVMValueRef new_resume_index = LLVMConstAllOnes(usize_type_ref);
+ LLVMBuildStore(g->builder, new_resume_index, g->cur_async_resume_index_ptr);
+ }
LLVMValueRef zero = LLVMConstNull(usize_type_ref);
LLVMValueRef all_ones = LLVMConstAllOnes(usize_type_ref);
+
LLVMValueRef prev_val = gen_maybe_atomic_op(g, LLVMAtomicRMWBinOpXor, g->cur_async_awaiter_ptr,
all_ones, LLVMAtomicOrderingAcquire);
@@ -2316,7 +2288,6 @@ static LLVMValueRef ir_render_return_begin(CodeGen *g, IrExecutable *executable,
LLVMBasicBlockRef resume_them_block = LLVMAppendBasicBlock(g->cur_fn_val, "ResumeThem");
LLVMValueRef switch_instr = LLVMBuildSwitch(g->builder, prev_val, resume_them_block, 2);
- LLVMBasicBlockRef switch_bb = LLVMGetInsertBlock(g->builder);
LLVMAddCase(switch_instr, zero, early_return_block);
LLVMAddCase(switch_instr, all_ones, bad_return_block);
@@ -2325,90 +2296,63 @@ static LLVMValueRef ir_render_return_begin(CodeGen *g, IrExecutable *executable,
LLVMPositionBuilderAtEnd(g->builder, bad_return_block);
gen_assertion(g, PanicMsgIdBadReturn, &instruction->base);
- // The caller has not done an await yet. So we suspend at the return instruction, until a
- // cancel or await is performed.
+ // There is no awaiter yet, but we're completely done.
LLVMPositionBuilderAtEnd(g->builder, early_return_block);
LLVMBuildRetVoid(g->builder);
- // Add a safety check for when getting resumed by the awaiter.
- LLVMPositionBuilderAtEnd(g->builder, resume_bb);
- LLVMBasicBlockRef after_resume_block = LLVMGetInsertBlock(g->builder);
- gen_assert_resume_id(g, &instruction->base, ResumeIdAwaitEarlyReturn, PanicMsgIdResumedFnPendingAwait,
- resume_them_block);
-
- // We need to resume the caller by tail calling them.
- // That will happen when rendering IrInstructionReturn after running the defers/errdefers.
- // We either got here from Entry (function call) or from the switch above
- g->cur_async_prev_val = LLVMBuildPhi(g->builder, usize_type_ref, "");
- LLVMValueRef incoming_values[] = { LLVMGetParam(g->cur_fn_val, 1), prev_val };
- LLVMBasicBlockRef incoming_blocks[] = { after_resume_block, switch_bb };
- LLVMAddIncoming(g->cur_async_prev_val, incoming_values, incoming_blocks, 2);
-
- g->cur_is_after_return = true;
- LLVMBuildStore(g->builder, g->cur_async_prev_val, g->cur_async_prev_val_field_ptr);
-
- if (!operand_has_bits) {
- return nullptr;
- }
-
- return get_handle_value(g, g->cur_ret_ptr, operand_type, get_pointer_to_type(g, operand_type, true));
-}
-
-static void set_tail_call_if_appropriate(CodeGen *g, LLVMValueRef call_inst) {
- LLVMSetTailCall(call_inst, true);
+ // We need to resume the caller by tail calling them,
+ // but first write through the result pointer and possibly
+ // error return trace pointer.
+ LLVMPositionBuilderAtEnd(g->builder, resume_them_block);
+
+ if (ret_type_has_bits) {
+ // If the awaiter result pointer is non-null, we need to copy the result to there.
+ LLVMBasicBlockRef copy_block = LLVMAppendBasicBlock(g->cur_fn_val, "CopyResult");
+ LLVMBasicBlockRef copy_end_block = LLVMAppendBasicBlock(g->cur_fn_val, "CopyResultEnd");
+ LLVMValueRef awaiter_ret_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, frame_ret_start + 1, "");
+ LLVMValueRef awaiter_ret_ptr = LLVMBuildLoad(g->builder, awaiter_ret_ptr_ptr, "");
+ LLVMValueRef zero_ptr = LLVMConstNull(LLVMTypeOf(awaiter_ret_ptr));
+ LLVMValueRef need_copy_bit = LLVMBuildICmp(g->builder, LLVMIntNE, awaiter_ret_ptr, zero_ptr, "");
+ LLVMBuildCondBr(g->builder, need_copy_bit, copy_block, copy_end_block);
+
+ LLVMPositionBuilderAtEnd(g->builder, copy_block);
+ LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);
+ LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, awaiter_ret_ptr, ptr_u8, "");
+ LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, g->cur_ret_ptr, ptr_u8, "");
+ bool is_volatile = false;
+ uint32_t abi_align = get_abi_alignment(g, ret_type);
+ LLVMValueRef byte_count_val = LLVMConstInt(usize_type_ref, type_size(g, ret_type), false);
+ ZigLLVMBuildMemCpy(g->builder,
+ dest_ptr_casted, abi_align,
+ src_ptr_casted, abi_align, byte_count_val, is_volatile);
+ LLVMBuildBr(g->builder, copy_end_block);
+
+ LLVMPositionBuilderAtEnd(g->builder, copy_end_block);
+ if (codegen_fn_has_err_ret_tracing_arg(g, ret_type)) {
+ LLVMValueRef awaiter_trace_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr,
+ frame_index_trace_arg(g, ret_type) + 1, "");
+ LLVMValueRef dest_trace_ptr = LLVMBuildLoad(g->builder, awaiter_trace_ptr_ptr, "");
+ LLVMValueRef my_err_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope);
+ LLVMValueRef args[] = { dest_trace_ptr, my_err_trace_val };
+ ZigLLVMBuildCall(g->builder, get_merge_err_ret_traces_fn_val(g), args, 2,
+ get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_FnInlineAuto, "");
+ }
+ }
+
+ // Resume the caller by tail calling them.
+ ZigType *any_frame_type = get_any_frame_type(g, ret_type);
+ LLVMValueRef their_frame_ptr = LLVMBuildIntToPtr(g->builder, prev_val, get_llvm_type(g, any_frame_type), "");
+ LLVMValueRef call_inst = gen_resume(g, nullptr, their_frame_ptr, ResumeIdReturn);
+ set_tail_call_if_appropriate(g, call_inst);
+ LLVMBuildRetVoid(g->builder);
}
static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrInstructionReturn *instruction) {
if (fn_is_async(g->cur_fn)) {
- LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
- ZigType *ret_type = g->cur_fn->type_entry->data.fn.fn_type_id.return_type;
- bool ret_type_has_bits = type_has_bits(ret_type);
-
- if (ir_want_runtime_safety(g, &instruction->base)) {
- LLVMValueRef new_resume_index = LLVMConstAllOnes(usize_type_ref);
- LLVMBuildStore(g->builder, new_resume_index, g->cur_async_resume_index_ptr);
- }
-
- if (ret_type_has_bits) {
- // If the awaiter result pointer is non-null, we need to copy the result to there.
- LLVMBasicBlockRef copy_block = LLVMAppendBasicBlock(g->cur_fn_val, "CopyResult");
- LLVMBasicBlockRef copy_end_block = LLVMAppendBasicBlock(g->cur_fn_val, "CopyResultEnd");
- LLVMValueRef awaiter_ret_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, frame_ret_start + 1, "");
- LLVMValueRef awaiter_ret_ptr = LLVMBuildLoad(g->builder, awaiter_ret_ptr_ptr, "");
- LLVMValueRef zero_ptr = LLVMConstNull(LLVMTypeOf(awaiter_ret_ptr));
- LLVMValueRef need_copy_bit = LLVMBuildICmp(g->builder, LLVMIntNE, awaiter_ret_ptr, zero_ptr, "");
- LLVMBuildCondBr(g->builder, need_copy_bit, copy_block, copy_end_block);
-
- LLVMPositionBuilderAtEnd(g->builder, copy_block);
- LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);
- LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, awaiter_ret_ptr, ptr_u8, "");
- LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, g->cur_ret_ptr, ptr_u8, "");
- bool is_volatile = false;
- uint32_t abi_align = get_abi_alignment(g, ret_type);
- LLVMValueRef byte_count_val = LLVMConstInt(usize_type_ref, type_size(g, ret_type), false);
- ZigLLVMBuildMemCpy(g->builder,
- dest_ptr_casted, abi_align,
- src_ptr_casted, abi_align, byte_count_val, is_volatile);
- LLVMBuildBr(g->builder, copy_end_block);
-
- LLVMPositionBuilderAtEnd(g->builder, copy_end_block);
- }
-
- // We need to resume the caller by tail calling them.
- ZigType *any_frame_type = get_any_frame_type(g, ret_type);
- LLVMValueRef one = LLVMConstInt(usize_type_ref, 1, false);
- LLVMValueRef mask_val = LLVMConstNot(one);
- LLVMValueRef masked_prev_val = LLVMBuildAnd(g->builder, get_cur_async_prev_val(g), mask_val, "");
- LLVMValueRef their_frame_ptr = LLVMBuildIntToPtr(g->builder, masked_prev_val,
- get_llvm_type(g, any_frame_type), "");
- LLVMValueRef call_inst = gen_resume(g, nullptr, their_frame_ptr, ResumeIdReturn, nullptr);
- set_tail_call_if_appropriate(g, call_inst);
- LLVMBuildRetVoid(g->builder);
-
- g->cur_is_after_return = false;
-
+ gen_async_return(g, instruction);
return nullptr;
}
+
if (want_first_arg_sret(g, &g->cur_fn->type_entry->data.fn.fn_type_id)) {
if (instruction->operand == nullptr) {
LLVMBuildRetVoid(g->builder);
@@ -3893,6 +3837,8 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
// even if prefix_arg_err_ret_stack is true, let the async function do its own
// initialization.
} else {
+ // async function called as a normal function
+
frame_result_loc = ir_llvm_value(g, instruction->frame_result_loc);
awaiter_init_val = LLVMBuildPtrToInt(g->builder, g->cur_frame_ptr, usize_type_ref, ""); // caller's own frame pointer
if (ret_has_bits) {
@@ -3912,7 +3858,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
if (prefix_arg_err_ret_stack) {
LLVMValueRef err_ret_trace_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc,
- frame_index_trace_arg(g, src_return_type), "");
+ frame_index_trace_arg(g, src_return_type) + 1, "");
LLVMValueRef my_err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope);
LLVMBuildStore(g->builder, my_err_ret_trace_val, err_ret_trace_ptr_ptr);
}
@@ -4018,7 +3964,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
}
if (instruction->is_async) {
- gen_resume(g, fn_val, frame_result_loc, ResumeIdCall, nullptr);
+ gen_resume(g, fn_val, frame_result_loc, ResumeIdCall);
if (instruction->new_stack != nullptr) {
return frame_result_loc;
}
@@ -4028,7 +3974,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
LLVMBasicBlockRef call_bb = gen_suspend_begin(g, "CallResume");
- LLVMValueRef call_inst = gen_resume(g, fn_val, frame_result_loc, ResumeIdCall, nullptr);
+ LLVMValueRef call_inst = gen_resume(g, fn_val, frame_result_loc, ResumeIdCall);
set_tail_call_if_appropriate(g, call_inst);
LLVMBuildRetVoid(g->builder);
@@ -4744,8 +4690,7 @@ static LLVMValueRef ir_render_error_return_trace(CodeGen *g, IrExecutable *execu
{
LLVMValueRef cur_err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope);
if (cur_err_ret_trace_val == nullptr) {
- ZigType *ptr_to_stack_trace_type = get_ptr_to_stack_trace_type(g);
- return LLVMConstNull(get_llvm_type(g, ptr_to_stack_trace_type));
+ return LLVMConstNull(get_llvm_type(g, ptr_to_stack_trace_type(g)));
}
return cur_err_ret_trace_val;
}
@@ -5505,60 +5450,6 @@ static LLVMValueRef ir_render_suspend_finish(CodeGen *g, IrExecutable *executabl
return nullptr;
}
-static LLVMValueRef ir_render_cancel(CodeGen *g, IrExecutable *executable, IrInstructionCancel *instruction) {
- LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
- LLVMValueRef zero = LLVMConstNull(usize_type_ref);
- LLVMValueRef all_ones = LLVMConstAllOnes(usize_type_ref);
- LLVMValueRef one = LLVMConstInt(usize_type_ref, 1, false);
- src_assert(instruction->frame->value.type->id == ZigTypeIdAnyFrame, instruction->base.source_node);
- ZigType *result_type = instruction->frame->value.type->data.any_frame.result_type;
-
- LLVMValueRef target_frame_ptr = ir_llvm_value(g, instruction->frame);
- LLVMBasicBlockRef resume_bb = gen_suspend_begin(g, "CancelResume");
-
- // supply null for the awaiter return pointer (no copy needed)
- if (type_has_bits(result_type)) {
- LLVMValueRef awaiter_ret_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, frame_ret_start + 1, "");
- LLVMBuildStore(g->builder, LLVMConstNull(LLVMGetElementType(LLVMTypeOf(awaiter_ret_ptr_ptr))),
- awaiter_ret_ptr_ptr);
- }
-
- // supply null for the error return trace pointer
- if (codegen_fn_has_err_ret_tracing_arg(g, result_type)) {
- LLVMValueRef err_ret_trace_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr,
- frame_index_trace_arg(g, result_type), "");
- LLVMBuildStore(g->builder, LLVMConstNull(LLVMGetElementType(LLVMTypeOf(err_ret_trace_ptr_ptr))),
- err_ret_trace_ptr_ptr);
- }
-
- LLVMValueRef awaiter_val = LLVMBuildPtrToInt(g->builder, g->cur_frame_ptr, usize_type_ref, "");
- LLVMValueRef awaiter_ored_val = LLVMBuildOr(g->builder, awaiter_val, one, "");
- LLVMValueRef awaiter_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, frame_awaiter_index, "");
-
- LLVMValueRef prev_val = gen_maybe_atomic_op(g, LLVMAtomicRMWBinOpXchg, awaiter_ptr, awaiter_ored_val,
- LLVMAtomicOrderingRelease);
-
- LLVMBasicBlockRef complete_suspend_block = LLVMAppendBasicBlock(g->cur_fn_val, "CancelSuspend");
- LLVMBasicBlockRef early_return_block = LLVMAppendBasicBlock(g->cur_fn_val, "EarlyReturn");
-
- LLVMValueRef switch_instr = LLVMBuildSwitch(g->builder, prev_val, resume_bb, 2);
- LLVMAddCase(switch_instr, zero, complete_suspend_block);
- LLVMAddCase(switch_instr, all_ones, early_return_block);
-
- LLVMPositionBuilderAtEnd(g->builder, complete_suspend_block);
- LLVMBuildRetVoid(g->builder);
-
- LLVMPositionBuilderAtEnd(g->builder, early_return_block);
- LLVMValueRef call_inst = gen_resume(g, nullptr, target_frame_ptr, ResumeIdAwaitEarlyReturn, awaiter_ored_val);
- set_tail_call_if_appropriate(g, call_inst);
- LLVMBuildRetVoid(g->builder);
-
- LLVMPositionBuilderAtEnd(g->builder, resume_bb);
- gen_assert_resume_id(g, &instruction->base, ResumeIdReturn, PanicMsgIdResumedACancelingFn, nullptr);
-
- return nullptr;
-}
-
static LLVMValueRef ir_render_await(CodeGen *g, IrExecutable *executable, IrInstructionAwaitGen *instruction) {
LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
LLVMValueRef zero = LLVMConstNull(usize_type_ref);
@@ -5568,8 +5459,9 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutable *executable, IrInst
// Prepare to be suspended
LLVMBasicBlockRef resume_bb = gen_suspend_begin(g, "AwaitResume");
+ LLVMBasicBlockRef end_bb = LLVMAppendBasicBlock(g->cur_fn_val, "AwaitEnd");
- // At this point resuming the function will do the correct thing.
+ // At this point resuming the function will continue from resume_bb.
// This code is as if it is running inside the suspend block.
// supply the awaiter return pointer
@@ -5591,15 +5483,15 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutable *executable, IrInst
LLVMValueRef my_err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope);
assert(my_err_ret_trace_val != nullptr);
LLVMValueRef err_ret_trace_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr,
- frame_index_trace_arg(g, result_type), "");
+ frame_index_trace_arg(g, result_type) + 1, "");
LLVMBuildStore(g->builder, my_err_ret_trace_val, err_ret_trace_ptr_ptr);
}
// caller's own frame pointer
LLVMValueRef awaiter_init_val = LLVMBuildPtrToInt(g->builder, g->cur_frame_ptr, usize_type_ref, "");
LLVMValueRef awaiter_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, frame_awaiter_index, "");
- LLVMValueRef prev_val = LLVMBuildAtomicRMW(g->builder, LLVMAtomicRMWBinOpXchg, awaiter_ptr, awaiter_init_val,
- LLVMAtomicOrderingRelease, g->is_single_threaded);
+ LLVMValueRef prev_val = gen_maybe_atomic_op(g, LLVMAtomicRMWBinOpXchg, awaiter_ptr, awaiter_init_val,
+ LLVMAtomicOrderingRelease);
LLVMBasicBlockRef bad_await_block = LLVMAppendBasicBlock(g->cur_fn_val, "BadAwait");
LLVMBasicBlockRef complete_suspend_block = LLVMAppendBasicBlock(g->cur_fn_val, "CompleteSuspend");
@@ -5615,20 +5507,42 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutable *executable, IrInst
LLVMPositionBuilderAtEnd(g->builder, bad_await_block);
gen_assertion(g, PanicMsgIdBadAwait, &instruction->base);
- // Early return: The async function has already completed, but it is suspending before setting the result,
- // populating the error return trace if applicable, and running the defers.
- // Tail resume it now, so that it can complete.
- LLVMPositionBuilderAtEnd(g->builder, early_return_block);
- LLVMValueRef call_inst = gen_resume(g, nullptr, target_frame_ptr, ResumeIdAwaitEarlyReturn, awaiter_init_val);
- set_tail_call_if_appropriate(g, call_inst);
- LLVMBuildRetVoid(g->builder);
-
// Rely on the target to resume us from suspension.
LLVMPositionBuilderAtEnd(g->builder, complete_suspend_block);
LLVMBuildRetVoid(g->builder);
+ // Early return: The async function has already completed. We must copy the result and
+ // the error return trace if applicable.
+ LLVMPositionBuilderAtEnd(g->builder, early_return_block);
+ if (type_has_bits(result_type) && result_loc != nullptr) {
+ LLVMValueRef their_result_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, frame_ret_start, "");
+ LLVMValueRef their_result_ptr = LLVMBuildLoad(g->builder, their_result_ptr_ptr, "");
+ LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);
+ LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, result_loc, ptr_u8, "");
+ LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, their_result_ptr, ptr_u8, "");
+ bool is_volatile = false;
+ uint32_t abi_align = get_abi_alignment(g, result_type);
+ LLVMValueRef byte_count_val = LLVMConstInt(usize_type_ref, type_size(g, result_type), false);
+ ZigLLVMBuildMemCpy(g->builder,
+ dest_ptr_casted, abi_align,
+ src_ptr_casted, abi_align, byte_count_val, is_volatile);
+ }
+ if (codegen_fn_has_err_ret_tracing_arg(g, result_type)) {
+ LLVMValueRef their_trace_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr,
+ frame_index_trace_arg(g, result_type), "");
+ LLVMValueRef src_trace_ptr = LLVMBuildLoad(g->builder, their_trace_ptr_ptr, "");
+ LLVMValueRef dest_trace_ptr = get_cur_err_ret_trace_val(g, instruction->base.scope);
+ LLVMValueRef args[] = { dest_trace_ptr, src_trace_ptr };
+ ZigLLVMBuildCall(g->builder, get_merge_err_ret_traces_fn_val(g), args, 2,
+ get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_FnInlineAuto, "");
+ }
+ LLVMBuildBr(g->builder, end_bb);
+
LLVMPositionBuilderAtEnd(g->builder, resume_bb);
gen_assert_resume_id(g, &instruction->base, ResumeIdReturn, PanicMsgIdResumedAnAwaitingFn, nullptr);
+ LLVMBuildBr(g->builder, end_bb);
+
+ LLVMPositionBuilderAtEnd(g->builder, end_bb);
if (type_has_bits(result_type) && result_loc != nullptr) {
return get_handle_value(g, result_loc, result_type, ptr_result_type);
}
@@ -5640,7 +5554,7 @@ static LLVMValueRef ir_render_resume(CodeGen *g, IrExecutable *executable, IrIns
ZigType *frame_type = instruction->frame->value.type;
assert(frame_type->id == ZigTypeIdAnyFrame);
- gen_resume(g, nullptr, frame, ResumeIdManual, nullptr);
+ gen_resume(g, nullptr, frame, ResumeIdManual);
return nullptr;
}
@@ -5651,18 +5565,6 @@ static LLVMValueRef ir_render_frame_size(CodeGen *g, IrExecutable *executable,
return gen_frame_size(g, fn_val);
}
-static LLVMValueRef ir_render_test_cancel_requested(CodeGen *g, IrExecutable *executable,
- IrInstructionTestCancelRequested *instruction)
-{
- if (!fn_is_async(g->cur_fn))
- return LLVMConstInt(LLVMInt1Type(), 0, false);
- if (g->cur_is_after_return) {
- return LLVMBuildTrunc(g->builder, get_cur_async_prev_val(g), LLVMInt1Type(), "");
- } else {
- zig_panic("TODO");
- }
-}
-
static LLVMValueRef ir_render_spill_begin(CodeGen *g, IrExecutable *executable,
IrInstructionSpillBegin *instruction)
{
@@ -5798,8 +5700,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
case IrInstructionIdDeclVarGen:
return ir_render_decl_var(g, executable, (IrInstructionDeclVarGen *)instruction);
- case IrInstructionIdReturnBegin:
- return ir_render_return_begin(g, executable, (IrInstructionReturnBegin *)instruction);
case IrInstructionIdReturn:
return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
case IrInstructionIdBinOp:
@@ -5918,8 +5818,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
return ir_render_align_cast(g, executable, (IrInstructionAlignCast *)instruction);
case IrInstructionIdErrorReturnTrace:
return ir_render_error_return_trace(g, executable, (IrInstructionErrorReturnTrace *)instruction);
- case IrInstructionIdCancel:
- return ir_render_cancel(g, executable, (IrInstructionCancel *)instruction);
case IrInstructionIdAtomicRmw:
return ir_render_atomic_rmw(g, executable, (IrInstructionAtomicRmw *)instruction);
case IrInstructionIdAtomicLoad:
@@ -5952,8 +5850,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
return ir_render_frame_size(g, executable, (IrInstructionFrameSizeGen *)instruction);
case IrInstructionIdAwaitGen:
return ir_render_await(g, executable, (IrInstructionAwaitGen *)instruction);
- case IrInstructionIdTestCancelRequested:
- return ir_render_test_cancel_requested(g, executable, (IrInstructionTestCancelRequested *)instruction);
case IrInstructionIdSpillBegin:
return ir_render_spill_begin(g, executable, (IrInstructionSpillBegin *)instruction);
case IrInstructionIdSpillEnd:
@@ -7060,9 +6956,9 @@ static void do_code_gen(CodeGen *g) {
ZigType *array_type = get_array_type(g, g->builtin_types.entry_usize, stack_trace_ptr_count);
err_ret_array_val = build_alloca(g, array_type, "error_return_trace_addresses", get_abi_alignment(g, array_type));
- // populate g->stack_trace_type
- (void)get_ptr_to_stack_trace_type(g);
- g->cur_err_ret_trace_val_stack = build_alloca(g, g->stack_trace_type, "error_return_trace", get_abi_alignment(g, g->stack_trace_type));
+ (void)get_llvm_type(g, get_stack_trace_type(g));
+ g->cur_err_ret_trace_val_stack = build_alloca(g, get_stack_trace_type(g), "error_return_trace",
+ get_abi_alignment(g, g->stack_trace_type));
} else {
g->cur_err_ret_trace_val_stack = nullptr;
}
@@ -7204,18 +7100,12 @@ static void do_code_gen(CodeGen *g) {
LLVMValueRef cur_ret_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, frame_ret_start, "");
g->cur_ret_ptr = LLVMBuildLoad(g->builder, cur_ret_ptr_ptr, "");
}
- if (codegen_fn_has_err_ret_tracing_arg(g, fn_type_id->return_type)) {
- uint32_t trace_field_index = frame_index_trace_arg(g, fn_type_id->return_type);
- g->cur_err_ret_trace_val_arg = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, trace_field_index, "");
- }
uint32_t trace_field_index_stack = UINT32_MAX;
if (codegen_fn_has_err_ret_tracing_stack(g, fn_table_entry, true)) {
trace_field_index_stack = frame_index_trace_stack(g, fn_type_id);
g->cur_err_ret_trace_val_stack = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr,
trace_field_index_stack, "");
}
- g->cur_async_prev_val_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr,
- frame_prev_val_index, "");
LLVMValueRef resume_index = LLVMBuildLoad(g->builder, resume_index_ptr, "");
LLVMValueRef switch_instr = LLVMBuildSwitch(g->builder, resume_index, bad_resume_block, 4);
@@ -7227,6 +7117,13 @@ static void do_code_gen(CodeGen *g) {
g->cur_resume_block_count += 1;
LLVMPositionBuilderAtEnd(g->builder, entry_block->llvm_block);
if (trace_field_index_stack != UINT32_MAX) {
+ if (codegen_fn_has_err_ret_tracing_arg(g, fn_type_id->return_type)) {
+ LLVMValueRef trace_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr,
+ frame_index_trace_arg(g, fn_type_id->return_type), "");
+ LLVMValueRef zero_ptr = LLVMConstNull(LLVMGetElementType(LLVMTypeOf(trace_ptr_ptr)));
+ LLVMBuildStore(g->builder, zero_ptr, trace_ptr_ptr);
+ }
+
LLVMValueRef trace_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr,
trace_field_index_stack, "");
LLVMValueRef trace_field_addrs = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr,
@@ -7273,8 +7170,6 @@ static void do_code_gen(CodeGen *g) {
LLVMDumpModule(g->module);
}
- // in release mode, we're sooooo confident that we've generated correct ir,
- // that we skip the verify module step in order to get better performance.
#ifndef NDEBUG
char *error = nullptr;
LLVMVerifyModule(g->module, LLVMAbortProcessAction, &error);
@@ -10157,6 +10052,11 @@ bool codegen_fn_has_err_ret_tracing_arg(CodeGen *g, ZigType *return_type) {
}
bool codegen_fn_has_err_ret_tracing_stack(CodeGen *g, ZigFn *fn, bool is_async) {
- return g->have_err_ret_tracing && fn->calls_or_awaits_errorable_fn &&
- (is_async || !codegen_fn_has_err_ret_tracing_arg(g, fn->type_entry->data.fn.fn_type_id.return_type));
+ if (is_async) {
+ return g->have_err_ret_tracing && (fn->calls_or_awaits_errorable_fn ||
+ codegen_fn_has_err_ret_tracing_arg(g, fn->type_entry->data.fn.fn_type_id.return_type));
+ } else {
+ return g->have_err_ret_tracing && fn->calls_or_awaits_errorable_fn &&
+ !codegen_fn_has_err_ret_tracing_arg(g, fn->type_entry->data.fn.fn_type_id.return_type);
+ }
}
diff --git a/src/ir.cpp b/src/ir.cpp
index 3564435ddd..3e80fad270 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -526,10 +526,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionReturn *) {
return IrInstructionIdReturn;
}
-static constexpr IrInstructionId ir_instruction_id(IrInstructionReturnBegin *) {
- return IrInstructionIdReturnBegin;
-}
-
static constexpr IrInstructionId ir_instruction_id(IrInstructionCast *) {
return IrInstructionIdCast;
}
@@ -974,10 +970,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionErrorUnion *) {
return IrInstructionIdErrorUnion;
}
-static constexpr IrInstructionId ir_instruction_id(IrInstructionCancel *) {
- return IrInstructionIdCancel;
-}
-
static constexpr IrInstructionId ir_instruction_id(IrInstructionAtomicRmw *) {
return IrInstructionIdAtomicRmw;
}
@@ -1062,10 +1054,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionResume *) {
return IrInstructionIdResume;
}
-static constexpr IrInstructionId ir_instruction_id(IrInstructionTestCancelRequested *) {
- return IrInstructionIdTestCancelRequested;
-}
-
static constexpr IrInstructionId ir_instruction_id(IrInstructionSpillBegin *) {
return IrInstructionIdSpillBegin;
}
@@ -1138,18 +1126,6 @@ static IrInstruction *ir_build_return(IrBuilder *irb, Scope *scope, AstNode *sou
return &return_instruction->base;
}
-static IrInstruction *ir_build_return_begin(IrBuilder *irb, Scope *scope, AstNode *source_node,
- IrInstruction *operand)
-{
- IrInstructionReturnBegin *return_instruction = ir_build_instruction(irb, scope, source_node);
- return_instruction->operand = operand;
-
- ir_ref_instruction(operand, irb->current_basic_block);
-
- return &return_instruction->base;
-}
-
-
static IrInstruction *ir_build_const_void(IrBuilder *irb, Scope *scope, AstNode *source_node) {
IrInstructionConst *const_instruction = ir_build_instruction(irb, scope, source_node);
const_instruction->base.value.type = irb->codegen->builtin_types.entry_void;
@@ -3284,16 +3260,6 @@ static IrInstruction *ir_build_suspend_finish(IrBuilder *irb, Scope *scope, AstN
return &instruction->base;
}
-static IrInstruction *ir_build_cancel(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *frame) {
- IrInstructionCancel *instruction = ir_build_instruction(irb, scope, source_node);
- instruction->base.value.type = irb->codegen->builtin_types.entry_void;
- instruction->frame = frame;
-
- ir_ref_instruction(frame, irb->current_basic_block);
-
- return &instruction->base;
-}
-
static IrInstruction *ir_build_await_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
IrInstruction *frame, ResultLoc *result_loc)
{
@@ -3331,13 +3297,6 @@ static IrInstruction *ir_build_resume(IrBuilder *irb, Scope *scope, AstNode *sou
return &instruction->base;
}
-static IrInstruction *ir_build_test_cancel_requested(IrBuilder *irb, Scope *scope, AstNode *source_node) {
- IrInstructionTestCancelRequested *instruction = ir_build_instruction(irb, scope, source_node);
- instruction->base.value.type = irb->codegen->builtin_types.entry_bool;
-
- return &instruction->base;
-}
-
static IrInstructionSpillBegin *ir_build_spill_begin(IrBuilder *irb, Scope *scope, AstNode *source_node,
IrInstruction *operand, SpillId spill_id)
{
@@ -3532,7 +3491,6 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
}
ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, return_value));
- return_value = ir_build_return_begin(irb, scope, node, return_value);
size_t defer_counts[2];
ir_count_defers(irb, scope, outer_scope, defer_counts);
@@ -3545,49 +3503,40 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
return result;
}
bool should_inline = ir_should_inline(irb->exec, scope);
- bool need_test_cancel = !should_inline && have_err_defers;
IrBasicBlock *err_block = ir_create_basic_block(irb, scope, "ErrRetErr");
- IrBasicBlock *normal_defers_block = ir_create_basic_block(irb, scope, "Defers");
- IrBasicBlock *ok_block = need_test_cancel ?
- ir_create_basic_block(irb, scope, "ErrRetOk") : normal_defers_block;
- IrBasicBlock *all_defers_block = have_err_defers ? ir_create_basic_block(irb, scope, "ErrDefers") : normal_defers_block;
+ IrBasicBlock *ok_block = ir_create_basic_block(irb, scope, "ErrRetOk");
+
+ if (!have_err_defers) {
+ ir_gen_defers_for_block(irb, scope, outer_scope, false);
+ }
IrInstruction *is_err = ir_build_test_err_src(irb, scope, node, return_value, false, true);
- IrInstruction *force_comptime = ir_build_const_bool(irb, scope, node, should_inline);
- IrInstruction *err_is_comptime;
+ IrInstruction *is_comptime;
if (should_inline) {
- err_is_comptime = force_comptime;
+ is_comptime = ir_build_const_bool(irb, scope, node, should_inline);
} else {
- err_is_comptime = ir_build_test_comptime(irb, scope, node, is_err);
+ is_comptime = ir_build_test_comptime(irb, scope, node, is_err);
}
- ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err, err_block, ok_block, err_is_comptime));
+ ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err, err_block, ok_block, is_comptime));
IrBasicBlock *ret_stmt_block = ir_create_basic_block(irb, scope, "RetStmt");
ir_set_cursor_at_end_and_append_block(irb, err_block);
+ if (have_err_defers) {
+ ir_gen_defers_for_block(irb, scope, outer_scope, true);
+ }
if (irb->codegen->have_err_ret_tracing && !should_inline) {
ir_build_save_err_ret_addr(irb, scope, node);
}
- ir_build_br(irb, scope, node, all_defers_block, err_is_comptime);
-
- if (need_test_cancel) {
- ir_set_cursor_at_end_and_append_block(irb, ok_block);
- IrInstruction *is_canceled = ir_build_test_cancel_requested(irb, scope, node);
- ir_mark_gen(ir_build_cond_br(irb, scope, node, is_canceled,
- all_defers_block, normal_defers_block, force_comptime));
- }
+ ir_build_br(irb, scope, node, ret_stmt_block, is_comptime);
- if (all_defers_block != normal_defers_block) {
- ir_set_cursor_at_end_and_append_block(irb, all_defers_block);
- ir_gen_defers_for_block(irb, scope, outer_scope, true);
- ir_build_br(irb, scope, node, ret_stmt_block, force_comptime);
+ ir_set_cursor_at_end_and_append_block(irb, ok_block);
+ if (have_err_defers) {
+ ir_gen_defers_for_block(irb, scope, outer_scope, false);
}
-
- ir_set_cursor_at_end_and_append_block(irb, normal_defers_block);
- ir_gen_defers_for_block(irb, scope, outer_scope, false);
- ir_build_br(irb, scope, node, ret_stmt_block, force_comptime);
+ ir_build_br(irb, scope, node, ret_stmt_block, is_comptime);
ir_set_cursor_at_end_and_append_block(irb, ret_stmt_block);
IrInstruction *result = ir_build_return(irb, scope, node, return_value);
@@ -3619,8 +3568,6 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, err_val));
IrInstructionSpillBegin *spill_begin = ir_build_spill_begin(irb, scope, node, err_val,
SpillIdRetErrCode);
- ir_build_return_begin(irb, scope, node, err_val);
- err_val = ir_build_spill_end(irb, scope, node, spill_begin);
ResultLocReturn *result_loc_ret = allocate(1);
result_loc_ret->base.id = ResultLocIdReturn;
ir_build_reset_result(irb, scope, node, &result_loc_ret->base);
@@ -3629,6 +3576,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
if (irb->codegen->have_err_ret_tracing && !should_inline) {
ir_build_save_err_ret_addr(irb, scope, node);
}
+ err_val = ir_build_spill_end(irb, scope, node, spill_begin);
IrInstruction *ret_inst = ir_build_return(irb, scope, node, err_val);
result_loc_ret->base.source_instruction = ret_inst;
}
@@ -3847,38 +3795,10 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode
return result;
// no need for save_err_ret_addr because this cannot return error
- // but if it is a canceled async function we do need to run the errdefers
+ // only generate unconditional defers
ir_mark_gen(ir_build_add_implicit_return_type(irb, child_scope, block_node, result));
- result = ir_mark_gen(ir_build_return_begin(irb, child_scope, block_node, result));
-
- size_t defer_counts[2];
- ir_count_defers(irb, child_scope, outer_block_scope, defer_counts);
- bool have_err_defers = defer_counts[ReturnKindError] > 0;
- if (!have_err_defers) {
- // only generate unconditional defers
- ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false);
- return ir_mark_gen(ir_build_return(irb, child_scope, result->source_node, result));
- }
- IrInstruction *is_canceled = ir_build_test_cancel_requested(irb, child_scope, block_node);
- IrBasicBlock *all_defers_block = ir_create_basic_block(irb, child_scope, "ErrDefers");
- IrBasicBlock *normal_defers_block = ir_create_basic_block(irb, child_scope, "Defers");
- IrBasicBlock *ret_stmt_block = ir_create_basic_block(irb, child_scope, "RetStmt");
- bool should_inline = ir_should_inline(irb->exec, child_scope);
- IrInstruction *errdefers_is_comptime = ir_build_const_bool(irb, child_scope, block_node,
- should_inline || !have_err_defers);
- ir_mark_gen(ir_build_cond_br(irb, child_scope, block_node, is_canceled,
- all_defers_block, normal_defers_block, errdefers_is_comptime));
-
- ir_set_cursor_at_end_and_append_block(irb, all_defers_block);
- ir_gen_defers_for_block(irb, child_scope, outer_block_scope, true);
- ir_build_br(irb, child_scope, block_node, ret_stmt_block, errdefers_is_comptime);
-
- ir_set_cursor_at_end_and_append_block(irb, normal_defers_block);
ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false);
- ir_build_br(irb, child_scope, block_node, ret_stmt_block, errdefers_is_comptime);
-
- ir_set_cursor_at_end_and_append_block(irb, ret_stmt_block);
return ir_mark_gen(ir_build_return(irb, child_scope, result->source_node, result));
}
@@ -7930,31 +7850,6 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo
return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, return_type, is_var_args);
}
-static IrInstruction *ir_gen_cancel(IrBuilder *irb, Scope *scope, AstNode *node) {
- assert(node->type == NodeTypeCancel);
-
- ZigFn *fn_entry = exec_fn_entry(irb->exec);
- if (!fn_entry) {
- add_node_error(irb->codegen, node, buf_sprintf("cancel outside function definition"));
- return irb->codegen->invalid_instruction;
- }
- ScopeSuspend *existing_suspend_scope = get_scope_suspend(scope);
- if (existing_suspend_scope) {
- if (!existing_suspend_scope->reported_err) {
- ErrorMsg *msg = add_node_error(irb->codegen, node, buf_sprintf("cannot cancel inside suspend block"));
- add_error_note(irb->codegen, msg, existing_suspend_scope->base.source_node, buf_sprintf("suspend block here"));
- existing_suspend_scope->reported_err = true;
- }
- return irb->codegen->invalid_instruction;
- }
-
- IrInstruction *operand = ir_gen_node_extra(irb, node->data.cancel_expr.expr, scope, LValPtr, nullptr);
- if (operand == irb->codegen->invalid_instruction)
- return irb->codegen->invalid_instruction;
-
- return ir_build_cancel(irb, scope, node, operand);
-}
-
static IrInstruction *ir_gen_resume(IrBuilder *irb, Scope *scope, AstNode *node) {
assert(node->type == NodeTypeResume);
@@ -8149,8 +8044,6 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval, result_loc);
case NodeTypeErrorSetDecl:
return ir_lval_wrap(irb, scope, ir_gen_err_set_decl(irb, scope, node), lval, result_loc);
- case NodeTypeCancel:
- return ir_lval_wrap(irb, scope, ir_gen_cancel(irb, scope, node), lval, result_loc);
case NodeTypeResume:
return ir_lval_wrap(irb, scope, ir_gen_resume(irb, scope, node), lval, result_loc);
case NodeTypeAwaitExpr:
@@ -8228,7 +8121,6 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
if (!instr_is_unreachable(result)) {
ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, result->source_node, result));
- result = ir_mark_gen(ir_build_return_begin(irb, scope, node, result));
// no need for save_err_ret_addr because this cannot return error
ir_mark_gen(ir_build_return(irb, scope, result->source_node, result));
}
@@ -8340,7 +8232,6 @@ static ConstExprValue *ir_exec_const_result(CodeGen *codegen, IrExecutable *exec
switch (instruction->id) {
case IrInstructionIdUnwrapErrPayload:
case IrInstructionIdUnionFieldPtr:
- case IrInstructionIdReturnBegin:
continue;
default:
break;
@@ -12745,17 +12636,17 @@ static IrInstruction *ir_analyze_instruction_add_implicit_return_type(IrAnalyze
return ir_const_void(ira, &instruction->base);
}
-static IrInstruction *ir_analyze_instruction_return_begin(IrAnalyze *ira, IrInstructionReturnBegin *instruction) {
+static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructionReturn *instruction) {
IrInstruction *operand = instruction->operand->child;
if (type_is_invalid(operand->value.type))
- return ira->codegen->invalid_instruction;
+ return ir_unreach_error(ira);
if (!instr_is_comptime(operand) && handle_is_ptr(ira->explicit_return_type)) {
// result location mechanism took care of it.
- IrInstruction *result = ir_build_return_begin(&ira->new_irb, instruction->base.scope,
- instruction->base.source_node, operand);
- copy_const_val(&result->value, &operand->value, true);
- return result;
+ IrInstruction *result = ir_build_return(&ira->new_irb, instruction->base.scope,
+ instruction->base.source_node, nullptr);
+ result->value.type = ira->codegen->builtin_types.entry_unreachable;
+ return ir_finish_anal(ira, result);
}
IrInstruction *casted_operand = ir_implicit_cast(ira, operand, ira->explicit_return_type);
@@ -12777,38 +12668,6 @@ static IrInstruction *ir_analyze_instruction_return_begin(IrAnalyze *ira, IrInst
return ir_unreach_error(ira);
}
- IrInstruction *result = ir_build_return_begin(&ira->new_irb, instruction->base.scope,
- instruction->base.source_node, casted_operand);
- copy_const_val(&result->value, &casted_operand->value, true);
- return result;
-}
-
-static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructionReturn *instruction) {
- IrInstruction *operand = instruction->operand->child;
- if (type_is_invalid(operand->value.type))
- return ir_unreach_error(ira);
-
- if (!instr_is_comptime(operand) && handle_is_ptr(ira->explicit_return_type)) {
- // result location mechanism took care of it.
- IrInstruction *result = ir_build_return(&ira->new_irb, instruction->base.scope,
- instruction->base.source_node, nullptr);
- result->value.type = ira->codegen->builtin_types.entry_unreachable;
- return ir_finish_anal(ira, result);
- }
-
- // This cast might have been already done from IrInstructionReturnBegin but it also
- // might not have, in the case of `try`.
- IrInstruction *casted_operand = ir_implicit_cast(ira, operand, ira->explicit_return_type);
- if (type_is_invalid(casted_operand->value.type)) {
- AstNode *source_node = ira->explicit_return_type_source_node;
- if (source_node != nullptr) {
- ErrorMsg *msg = ira->codegen->errors.last();
- add_error_note(ira->codegen, msg, source_node,
- buf_sprintf("return type declared here"));
- }
- return ir_unreach_error(ira);
- }
-
IrInstruction *result = ir_build_return(&ira->new_irb, instruction->base.scope,
instruction->base.source_node, casted_operand);
result->value.type = ira->codegen->builtin_types.entry_unreachable;
@@ -14540,8 +14399,8 @@ static bool exec_has_err_ret_trace(CodeGen *g, IrExecutable *exec) {
static IrInstruction *ir_analyze_instruction_error_return_trace(IrAnalyze *ira,
IrInstructionErrorReturnTrace *instruction)
{
+ ZigType *ptr_to_stack_trace_type = get_pointer_to_type(ira->codegen, get_stack_trace_type(ira->codegen), false);
if (instruction->optional == IrInstructionErrorReturnTrace::Null) {
- ZigType *ptr_to_stack_trace_type = get_ptr_to_stack_trace_type(ira->codegen);
ZigType *optional_type = get_optional_type(ira->codegen, ptr_to_stack_trace_type);
if (!exec_has_err_ret_trace(ira->codegen, ira->new_irb.exec)) {
IrInstruction *result = ir_const(ira, &instruction->base, optional_type);
@@ -14559,7 +14418,7 @@ static IrInstruction *ir_analyze_instruction_error_return_trace(IrAnalyze *ira,
assert(ira->codegen->have_err_ret_tracing);
IrInstruction *new_instruction = ir_build_error_return_trace(&ira->new_irb, instruction->base.scope,
instruction->base.source_node, instruction->optional);
- new_instruction->value.type = get_ptr_to_stack_trace_type(ira->codegen);
+ new_instruction->value.type = ptr_to_stack_trace_type;
return new_instruction;
}
}
@@ -15800,6 +15659,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
if (impl_fn_type_id->cc == CallingConventionAsync && parent_fn_entry->inferred_async_node == nullptr) {
parent_fn_entry->inferred_async_node = fn_ref->source_node;
+ parent_fn_entry->inferred_async_fn = impl_fn;
}
IrInstructionCallGen *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base,
@@ -15923,6 +15783,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
if (fn_type_id->cc == CallingConventionAsync && parent_fn_entry->inferred_async_node == nullptr) {
parent_fn_entry->inferred_async_node = fn_ref->source_node;
+ parent_fn_entry->inferred_async_fn = fn_entry;
}
IrInstruction *result_loc;
@@ -24702,21 +24563,6 @@ static IrInstruction *analyze_frame_ptr_to_anyframe_T(IrAnalyze *ira, IrInstruct
return casted_frame;
}
-static IrInstruction *ir_analyze_instruction_cancel(IrAnalyze *ira, IrInstructionCancel *instruction) {
- IrInstruction *frame = analyze_frame_ptr_to_anyframe_T(ira, &instruction->base, instruction->frame->child);
- if (type_is_invalid(frame->value.type))
- return ira->codegen->invalid_instruction;
-
- ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
- ir_assert(fn_entry != nullptr, &instruction->base);
-
- if (fn_entry->inferred_async_node == nullptr) {
- fn_entry->inferred_async_node = instruction->base.source_node;
- }
-
- return ir_build_cancel(&ira->new_irb, instruction->base.scope, instruction->base.source_node, frame);
-}
-
static IrInstruction *ir_analyze_instruction_await(IrAnalyze *ira, IrInstructionAwaitSrc *instruction) {
IrInstruction *frame = analyze_frame_ptr_to_anyframe_T(ira, &instruction->base, instruction->frame->child);
if (type_is_invalid(frame->value.type))
@@ -24772,15 +24618,6 @@ static IrInstruction *ir_analyze_instruction_resume(IrAnalyze *ira, IrInstructio
return ir_build_resume(&ira->new_irb, instruction->base.scope, instruction->base.source_node, casted_frame);
}
-static IrInstruction *ir_analyze_instruction_test_cancel_requested(IrAnalyze *ira,
- IrInstructionTestCancelRequested *instruction)
-{
- if (ir_should_inline(ira->new_irb.exec, instruction->base.scope)) {
- return ir_const_bool(ira, &instruction->base, false);
- }
- return ir_build_test_cancel_requested(&ira->new_irb, instruction->base.scope, instruction->base.source_node);
-}
-
static IrInstruction *ir_analyze_instruction_spill_begin(IrAnalyze *ira, IrInstructionSpillBegin *instruction) {
if (ir_should_inline(ira->new_irb.exec, instruction->base.scope))
return ir_const_void(ira, &instruction->base);
@@ -24848,8 +24685,6 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
case IrInstructionIdAwaitGen:
zig_unreachable();
- case IrInstructionIdReturnBegin:
- return ir_analyze_instruction_return_begin(ira, (IrInstructionReturnBegin *)instruction);
case IrInstructionIdReturn:
return ir_analyze_instruction_return(ira, (IrInstructionReturn *)instruction);
case IrInstructionIdConst:
@@ -25070,8 +24905,6 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
return ir_analyze_instruction_error_return_trace(ira, (IrInstructionErrorReturnTrace *)instruction);
case IrInstructionIdErrorUnion:
return ir_analyze_instruction_error_union(ira, (IrInstructionErrorUnion *)instruction);
- case IrInstructionIdCancel:
- return ir_analyze_instruction_cancel(ira, (IrInstructionCancel *)instruction);
case IrInstructionIdAtomicRmw:
return ir_analyze_instruction_atomic_rmw(ira, (IrInstructionAtomicRmw *)instruction);
case IrInstructionIdAtomicLoad:
@@ -25114,8 +24947,6 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
return ir_analyze_instruction_resume(ira, (IrInstructionResume *)instruction);
case IrInstructionIdAwaitSrc:
return ir_analyze_instruction_await(ira, (IrInstructionAwaitSrc *)instruction);
- case IrInstructionIdTestCancelRequested:
- return ir_analyze_instruction_test_cancel_requested(ira, (IrInstructionTestCancelRequested *)instruction);
case IrInstructionIdSpillBegin:
return ir_analyze_instruction_spill_begin(ira, (IrInstructionSpillBegin *)instruction);
case IrInstructionIdSpillEnd:
@@ -25209,7 +25040,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdStorePtr:
case IrInstructionIdCallSrc:
case IrInstructionIdCallGen:
- case IrInstructionIdReturnBegin:
case IrInstructionIdReturn:
case IrInstructionIdUnreachable:
case IrInstructionIdSetCold:
@@ -25235,7 +25065,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdPtrType:
case IrInstructionIdSetAlignStack:
case IrInstructionIdExport:
- case IrInstructionIdCancel:
case IrInstructionIdSaveErrRetAddr:
case IrInstructionIdAddImplicitReturnType:
case IrInstructionIdAtomicRmw:
@@ -25355,7 +25184,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdHasDecl:
case IrInstructionIdAllocaSrc:
case IrInstructionIdAllocaGen:
- case IrInstructionIdTestCancelRequested:
case IrInstructionIdSpillEnd:
return false;
diff --git a/src/ir_print.cpp b/src/ir_print.cpp
index 63f3711266..7580f19059 100644
--- a/src/ir_print.cpp
+++ b/src/ir_print.cpp
@@ -64,12 +64,6 @@ static void ir_print_other_block(IrPrint *irp, IrBasicBlock *bb) {
}
}
-static void ir_print_return_begin(IrPrint *irp, IrInstructionReturnBegin *instruction) {
- fprintf(irp->f, "@returnBegin(");
- ir_print_other_instruction(irp, instruction->operand);
- fprintf(irp->f, ")");
-}
-
static void ir_print_return(IrPrint *irp, IrInstructionReturn *instruction) {
fprintf(irp->f, "return ");
ir_print_other_instruction(irp, instruction->operand);
@@ -1394,11 +1388,6 @@ static void ir_print_error_union(IrPrint *irp, IrInstructionErrorUnion *instruct
ir_print_other_instruction(irp, instruction->payload);
}
-static void ir_print_cancel(IrPrint *irp, IrInstructionCancel *instruction) {
- fprintf(irp->f, "cancel ");
- ir_print_other_instruction(irp, instruction->frame);
-}
-
static void ir_print_atomic_rmw(IrPrint *irp, IrInstructionAtomicRmw *instruction) {
fprintf(irp->f, "@atomicRmw(");
if (instruction->operand_type != nullptr) {
@@ -1549,10 +1538,6 @@ static void ir_print_await_gen(IrPrint *irp, IrInstructionAwaitGen *instruction)
fprintf(irp->f, ")");
}
-static void ir_print_test_cancel_requested(IrPrint *irp, IrInstructionTestCancelRequested *instruction) {
- fprintf(irp->f, "@testCancelRequested()");
-}
-
static void ir_print_spill_begin(IrPrint *irp, IrInstructionSpillBegin *instruction) {
fprintf(irp->f, "@spillBegin(");
ir_print_other_instruction(irp, instruction->operand);
@@ -1570,9 +1555,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
switch (instruction->id) {
case IrInstructionIdInvalid:
zig_unreachable();
- case IrInstructionIdReturnBegin:
- ir_print_return_begin(irp, (IrInstructionReturnBegin *)instruction);
- break;
case IrInstructionIdReturn:
ir_print_return(irp, (IrInstructionReturn *)instruction);
break;
@@ -1966,9 +1948,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
case IrInstructionIdErrorUnion:
ir_print_error_union(irp, (IrInstructionErrorUnion *)instruction);
break;
- case IrInstructionIdCancel:
- ir_print_cancel(irp, (IrInstructionCancel *)instruction);
- break;
case IrInstructionIdAtomicRmw:
ir_print_atomic_rmw(irp, (IrInstructionAtomicRmw *)instruction);
break;
@@ -2047,9 +2026,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
case IrInstructionIdAwaitGen:
ir_print_await_gen(irp, (IrInstructionAwaitGen *)instruction);
break;
- case IrInstructionIdTestCancelRequested:
- ir_print_test_cancel_requested(irp, (IrInstructionTestCancelRequested *)instruction);
- break;
case IrInstructionIdSpillBegin:
ir_print_spill_begin(irp, (IrInstructionSpillBegin *)instruction);
break;
diff --git a/src/parser.cpp b/src/parser.cpp
index 82312aacf3..afe5735a06 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -1167,7 +1167,6 @@ static AstNode *ast_parse_prefix_expr(ParseContext *pc) {
// <- AsmExpr
// / IfExpr
// / KEYWORD_break BreakLabel? Expr?
-// / KEYWORD_cancel Expr
// / KEYWORD_comptime Expr
// / KEYWORD_continue BreakLabel?
// / KEYWORD_resume Expr
@@ -1195,14 +1194,6 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc) {
return res;
}
- Token *cancel = eat_token_if(pc, TokenIdKeywordCancel);
- if (cancel != nullptr) {
- AstNode *expr = ast_expect(pc, ast_parse_expr);
- AstNode *res = ast_create_node(pc, NodeTypeCancel, cancel);
- res->data.cancel_expr.expr = expr;
- return res;
- }
-
Token *comptime = eat_token_if(pc, TokenIdKeywordCompTime);
if (comptime != nullptr) {
AstNode *expr = ast_expect(pc, ast_parse_expr);
@@ -3035,9 +3026,6 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
case NodeTypeErrorSetDecl:
visit_node_list(&node->data.err_set_decl.decls, visit, context);
break;
- case NodeTypeCancel:
- visit_field(&node->data.cancel_expr.expr, visit, context);
- break;
case NodeTypeResume:
visit_field(&node->data.resume_expr.expr, visit, context);
break;
diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp
index 38c6c7153e..84f3f2c0ec 100644
--- a/src/tokenizer.cpp
+++ b/src/tokenizer.cpp
@@ -114,7 +114,6 @@ static const struct ZigKeyword zig_keywords[] = {
{"async", TokenIdKeywordAsync},
{"await", TokenIdKeywordAwait},
{"break", TokenIdKeywordBreak},
- {"cancel", TokenIdKeywordCancel},
{"catch", TokenIdKeywordCatch},
{"comptime", TokenIdKeywordCompTime},
{"const", TokenIdKeywordConst},
@@ -1531,7 +1530,6 @@ const char * token_name(TokenId id) {
case TokenIdKeywordAwait: return "await";
case TokenIdKeywordResume: return "resume";
case TokenIdKeywordSuspend: return "suspend";
- case TokenIdKeywordCancel: return "cancel";
case TokenIdKeywordAlign: return "align";
case TokenIdKeywordAnd: return "and";
case TokenIdKeywordAnyFrame: return "anyframe";
diff --git a/src/tokenizer.hpp b/src/tokenizer.hpp
index 98bdfea907..ce62f5dc87 100644
--- a/src/tokenizer.hpp
+++ b/src/tokenizer.hpp
@@ -58,7 +58,6 @@ enum TokenId {
TokenIdKeywordAsync,
TokenIdKeywordAwait,
TokenIdKeywordBreak,
- TokenIdKeywordCancel,
TokenIdKeywordCatch,
TokenIdKeywordCompTime,
TokenIdKeywordConst,
diff --git a/std/event/fs.zig b/std/event/fs.zig
index 73a296ca3f..d6d8f2faef 100644
--- a/std/event/fs.zig
+++ b/std/event/fs.zig
@@ -1301,7 +1301,7 @@ async fn testFsWatch(loop: *Loop) !void {
const ev = try async watch.channel.get();
var ev_consumed = false;
- defer if (!ev_consumed) cancel ev;
+ defer if (!ev_consumed) await ev;
// overwrite line 2
const fd = try await try async openReadWrite(loop, file_path, File.default_mode);
diff --git a/std/event/future.zig b/std/event/future.zig
index e5f6d984ce..45bb7759c5 100644
--- a/std/event/future.zig
+++ b/std/event/future.zig
@@ -110,7 +110,7 @@ async fn testFuture(loop: *Loop) void {
const b_result = await b;
const result = a_result + b_result;
- cancel c;
+ await c;
testing.expect(result == 12);
}
diff --git a/std/event/group.zig b/std/event/group.zig
index 1fc4a61e93..f96b938f80 100644
--- a/std/event/group.zig
+++ b/std/event/group.zig
@@ -27,17 +27,6 @@ pub fn Group(comptime ReturnType: type) type {
};
}
- /// Cancel all the outstanding frames. Can be called even if wait was already called.
- pub fn deinit(self: *Self) void {
- while (self.frame_stack.pop()) |node| {
- cancel node.data;
- }
- while (self.alloc_stack.pop()) |node| {
- cancel node.data;
- self.lock.loop.allocator.destroy(node);
- }
- }
-
/// Add a frame to the group. Thread-safe.
pub fn add(self: *Self, handle: anyframe->ReturnType) (error{OutOfMemory}!void) {
const node = try self.lock.loop.allocator.create(Stack.Node);
@@ -64,13 +53,14 @@ pub fn Group(comptime ReturnType: type) type {
const held = self.lock.acquire();
defer held.release();
+ var result: ReturnType = {};
+
while (self.frame_stack.pop()) |node| {
if (Error == void) {
await node.data;
} else {
(await node.data) catch |err| {
- self.deinit();
- return err;
+ result = err;
};
}
}
@@ -81,11 +71,11 @@ pub fn Group(comptime ReturnType: type) type {
await handle;
} else {
(await handle) catch |err| {
- self.deinit();
- return err;
+ result = err;
};
}
}
+ return result;
}
};
}
diff --git a/std/event/net.zig b/std/event/net.zig
index 2a28a0ef93..bed665dcdc 100644
--- a/std/event/net.zig
+++ b/std/event/net.zig
@@ -54,7 +54,7 @@ pub const Server = struct {
self.listen_address = std.net.Address.initPosix(try os.getsockname(sockfd));
self.accept_frame = async Server.handler(self);
- errdefer cancel self.accept_frame.?;
+ errdefer await self.accept_frame.?;
self.listen_resume_node.handle = self.accept_frame.?;
try self.loop.linuxAddFd(sockfd, &self.listen_resume_node, os.EPOLLIN | os.EPOLLOUT | os.EPOLLET);
@@ -71,7 +71,7 @@ pub const Server = struct {
}
pub fn deinit(self: *Server) void {
- if (self.accept_frame) |accept_frame| cancel accept_frame;
+ if (self.accept_frame) |accept_frame| await accept_frame;
if (self.sockfd) |sockfd| os.close(sockfd);
}
@@ -274,13 +274,9 @@ test "listen on a port, send bytes, receive bytes" {
const self = @fieldParentPtr(Self, "tcp_server", tcp_server);
var socket = _socket; // TODO https://github.com/ziglang/zig/issues/1592
defer socket.close();
- // TODO guarantee elision of this allocation
const next_handler = errorableHandler(self, _addr, socket) catch |err| {
std.debug.panic("unable to handle connection: {}\n", err);
};
- suspend {
- cancel @frame();
- }
}
async fn errorableHandler(self: *Self, _addr: *const std.net.Address, _socket: File) !void {
const addr = _addr.*; // TODO https://github.com/ziglang/zig/issues/1592
diff --git a/std/zig/parse.zig b/std/zig/parse.zig
index 600178cdce..077870a9ca 100644
--- a/std/zig/parse.zig
+++ b/std/zig/parse.zig
@@ -814,7 +814,6 @@ fn parsePrefixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
/// <- AsmExpr
/// / IfExpr
/// / KEYWORD_break BreakLabel? Expr?
-/// / KEYWORD_cancel Expr
/// / KEYWORD_comptime Expr
/// / KEYWORD_continue BreakLabel?
/// / KEYWORD_resume Expr
@@ -839,20 +838,6 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
return &node.base;
}
- if (eatToken(it, .Keyword_cancel)) |token| {
- const expr_node = try expectNode(arena, it, tree, parseExpr, AstError{
- .ExpectedExpr = AstError.ExpectedExpr{ .token = it.index },
- });
- const node = try arena.create(Node.PrefixOp);
- node.* = Node.PrefixOp{
- .base = Node{ .id = .PrefixOp },
- .op_token = token,
- .op = Node.PrefixOp.Op.Cancel,
- .rhs = expr_node,
- };
- return &node.base;
- }
-
if (eatToken(it, .Keyword_comptime)) |token| {
const expr_node = try expectNode(arena, it, tree, parseExpr, AstError{
.ExpectedExpr = AstError.ExpectedExpr{ .token = it.index },
diff --git a/std/zig/parser_test.zig b/std/zig/parser_test.zig
index 5f2a3934fd..c5c740353e 100644
--- a/std/zig/parser_test.zig
+++ b/std/zig/parser_test.zig
@@ -2115,10 +2115,10 @@ test "zig fmt: async functions" {
\\ await p;
\\}
\\
- \\test "suspend, resume, cancel" {
+ \\test "suspend, resume, await" {
\\ const p: anyframe = async testAsyncSeq();
\\ resume p;
- \\ cancel p;
+ \\ await p;
\\}
\\
);
diff --git a/std/zig/tokenizer.zig b/std/zig/tokenizer.zig
index 9de20c39f2..4d4ceb07db 100644
--- a/std/zig/tokenizer.zig
+++ b/std/zig/tokenizer.zig
@@ -21,7 +21,6 @@ pub const Token = struct {
Keyword{ .bytes = "await", .id = Id.Keyword_await },
Keyword{ .bytes = "break", .id = Id.Keyword_break },
Keyword{ .bytes = "catch", .id = Id.Keyword_catch },
- Keyword{ .bytes = "cancel", .id = Id.Keyword_cancel },
Keyword{ .bytes = "comptime", .id = Id.Keyword_comptime },
Keyword{ .bytes = "const", .id = Id.Keyword_const },
Keyword{ .bytes = "continue", .id = Id.Keyword_continue },
@@ -151,7 +150,6 @@ pub const Token = struct {
Keyword_async,
Keyword_await,
Keyword_break,
- Keyword_cancel,
Keyword_catch,
Keyword_comptime,
Keyword_const,
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index c07786d462..f53b1c9707 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -61,13 +61,15 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"runtime-known async function called",
\\export fn entry() void {
+ \\ _ = async amain();
+ \\}
+ \\fn amain() void {
\\ var ptr = afunc;
\\ _ = ptr();
\\}
- \\
\\async fn afunc() void {}
,
- "tmp.zig:3:12: error: function is not comptime-known; @asyncCall required",
+ "tmp.zig:6:12: error: function is not comptime-known; @asyncCall required",
);
cases.add(
@@ -3388,7 +3390,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\
\\export fn entry() usize { return @sizeOf(@typeOf(Foo)); }
,
- "tmp.zig:5:18: error: unable to evaluate constant expression",
+ "tmp.zig:5:25: error: unable to evaluate constant expression",
"tmp.zig:2:12: note: called from here",
"tmp.zig:2:8: note: called from here",
);
diff --git a/test/stage1/behavior.zig b/test/stage1/behavior.zig
index dba43268e2..6ec1521048 100644
--- a/test/stage1/behavior.zig
+++ b/test/stage1/behavior.zig
@@ -41,7 +41,6 @@ comptime {
_ = @import("behavior/bugs/920.zig");
_ = @import("behavior/byteswap.zig");
_ = @import("behavior/byval_arg_var.zig");
- _ = @import("behavior/cancel.zig");
_ = @import("behavior/cast.zig");
_ = @import("behavior/const_slice_child.zig");
_ = @import("behavior/defer.zig");
diff --git a/test/stage1/behavior/async_fn.zig b/test/stage1/behavior/async_fn.zig
index 2d76b47244..ec0c9e52a6 100644
--- a/test/stage1/behavior/async_fn.zig
+++ b/test/stage1/behavior/async_fn.zig
@@ -150,7 +150,7 @@ test "coroutine suspend, resume" {
seq('a');
var f = async testAsyncSeq();
seq('c');
- cancel f;
+ await f;
seq('g');
}
@@ -271,7 +271,6 @@ test "async function with dot syntax" {
}
};
const p = async S.foo();
- // can't cancel in tests because they are non-async functions
expect(S.y == 2);
}
@@ -286,7 +285,7 @@ test "async fn pointer in a struct field" {
comptime expect(@typeOf(f) == anyframe->void);
expect(data == 2);
resume f;
- expect(data == 2);
+ expect(data == 4);
_ = async doTheAwait(f);
expect(data == 4);
}
@@ -394,7 +393,6 @@ async fn printTrace(p: anyframe->(anyerror!void)) void {
test "break from suspend" {
var my_result: i32 = 1;
const p = async testBreakFromSuspend(&my_result);
- // can't cancel here
std.testing.expect(my_result == 2);
}
async fn testBreakFromSuspend(my_result: *i32) void {
@@ -530,45 +528,6 @@ test "call async function which has struct return type" {
S.doTheTest();
}
-test "errdefers in scope get run when canceling async fn call" {
- const S = struct {
- var frame: anyframe = undefined;
- var x: u32 = 0;
-
- fn doTheTest() void {
- x = 9;
- _ = async cancelIt();
- resume frame;
- expect(x == 6);
-
- x = 9;
- _ = async awaitIt();
- resume frame;
- expect(x == 11);
- }
-
- fn cancelIt() void {
- var f = async func();
- cancel f;
- }
-
- fn awaitIt() void {
- var f = async func();
- await f;
- }
-
- fn func() void {
- defer x += 1;
- errdefer x /= 2;
- defer x += 1;
- suspend {
- frame = @frame();
- }
- }
- };
- S.doTheTest();
-}
-
test "pass string literal to async function" {
const S = struct {
var frame: anyframe = undefined;
@@ -590,7 +549,7 @@ test "pass string literal to async function" {
S.doTheTest();
}
-test "cancel inside an errdefer" {
+test "await inside an errdefer" {
const S = struct {
var frame: anyframe = undefined;
@@ -601,7 +560,7 @@ test "cancel inside an errdefer" {
fn amainWrap() !void {
var foo = async func();
- errdefer cancel foo;
+ errdefer await foo;
return error.Bad;
}
@@ -614,35 +573,6 @@ test "cancel inside an errdefer" {
S.doTheTest();
}
-test "combining try with errdefer cancel" {
- const S = struct {
- var frame: anyframe = undefined;
- var ok = false;
-
- fn doTheTest() void {
- _ = async amain();
- resume frame;
- expect(ok);
- }
-
- fn amain() !void {
- var f = async func("https://example.com/");
- errdefer cancel f;
-
- _ = try await f;
- }
-
- fn func(url: []const u8) ![]u8 {
- errdefer ok = true;
- frame = @frame();
- suspend;
- return error.Bad;
- }
-
- };
- S.doTheTest();
-}
-
test "try in an async function with error union and non-zero-bit payload" {
const S = struct {
var frame: anyframe = undefined;
@@ -730,14 +660,22 @@ fn testAsyncAwaitTypicalUsage(comptime simulate_fail_download: bool, comptime si
fn amain() !void {
const allocator = std.heap.direct_allocator; // TODO once we have the debug allocator, use that, so that this can detect leaks
var download_frame = async fetchUrl(allocator, "https://example.com/");
- errdefer cancel download_frame;
+ var download_awaited = false;
+ errdefer if (!download_awaited) {
+ if (await download_frame) |x| allocator.free(x) else |_| {}
+ };
var file_frame = async readFile(allocator, "something.txt");
- errdefer cancel file_frame;
+ var file_awaited = false;
+ errdefer if (!file_awaited) {
+ if (await file_frame) |x| allocator.free(x) else |_| {}
+ };
+ download_awaited = true;
const download_text = try await download_frame;
defer allocator.free(download_text);
+ file_awaited = true;
const file_text = try await file_frame;
defer allocator.free(file_text);
diff --git a/test/stage1/behavior/cancel.zig b/test/stage1/behavior/cancel.zig
deleted file mode 100644
index 5dedb20159..0000000000
--- a/test/stage1/behavior/cancel.zig
+++ /dev/null
@@ -1,115 +0,0 @@
-const std = @import("std");
-const expect = std.testing.expect;
-
-var defer_f1: bool = false;
-var defer_f2: bool = false;
-var defer_f3: bool = false;
-var f3_frame: anyframe = undefined;
-
-test "cancel forwards" {
- _ = async atest1();
- resume f3_frame;
-}
-
-fn atest1() void {
- const p = async f1();
- cancel &p;
- expect(defer_f1);
- expect(defer_f2);
- expect(defer_f3);
-}
-
-async fn f1() void {
- defer {
- defer_f1 = true;
- }
- var f2_frame = async f2();
- await f2_frame;
-}
-
-async fn f2() void {
- defer {
- defer_f2 = true;
- }
- f3();
-}
-
-async fn f3() void {
- f3_frame = @frame();
- defer {
- defer_f3 = true;
- }
- suspend;
-}
-
-var defer_b1: bool = false;
-var defer_b2: bool = false;
-var defer_b3: bool = false;
-var defer_b4: bool = false;
-
-test "cancel backwards" {
- var b1_frame = async b1();
- resume b4_handle;
- _ = async awaitAFrame(&b1_frame);
- expect(defer_b1);
- expect(defer_b2);
- expect(defer_b3);
- expect(defer_b4);
-}
-
-async fn b1() void {
- defer {
- defer_b1 = true;
- }
- b2();
-}
-
-var b4_handle: anyframe->void = undefined;
-
-async fn b2() void {
- const b3_handle = async b3();
- resume b4_handle;
- defer {
- defer_b2 = true;
- }
- const value = await b3_handle;
- expect(value == 1234);
-}
-
-async fn b3() i32 {
- defer {
- defer_b3 = true;
- }
- b4();
- return 1234;
-}
-
-async fn b4() void {
- defer {
- defer_b4 = true;
- }
- suspend {
- b4_handle = @frame();
- }
- suspend;
-}
-
-fn awaitAFrame(f: anyframe->void) void {
- await f;
-}
-
-test "cancel on a non-pointer" {
- const S = struct {
- fn doTheTest() void {
- _ = async atest();
- }
- fn atest() void {
- var f = async func();
- cancel f;
- }
- fn func() void {
- suspend;
- }
- };
- S.doTheTest();
-}
--
cgit v1.2.3
From 2151f84d59f8af6e28570cb01a3a134c7b068fa2 Mon Sep 17 00:00:00 2001
From: Vexu <15308111+Vexu@users.noreply.github.com>
Date: Fri, 16 Aug 2019 12:24:06 +0300
Subject: implement new async syntax in self-hosted compiler
---
doc/langref.html.in | 6 ++--
src-self-hosted/ir.zig | 1 -
src-self-hosted/translate_c.zig | 3 +-
src/parser.cpp | 44 +++++++++-----------------
std/zig/ast.zig | 37 ++--------------------
std/zig/parse.zig | 69 ++++++++++-------------------------------
std/zig/parser_test.zig | 4 +--
std/zig/render.zig | 22 ++-----------
8 files changed, 41 insertions(+), 145 deletions(-)
(limited to 'src/parser.cpp')
diff --git a/doc/langref.html.in b/doc/langref.html.in
index e02a406bd4..2e56bc6557 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -9987,7 +9987,7 @@ TypeExpr <- PrefixTypeOp* ErrorUnionExpr
ErrorUnionExpr <- SuffixExpr (EXCLAMATIONMARK TypeExpr)?
SuffixExpr
- <- AsyncPrefix PrimaryTypeExpr SuffixOp* FnCallArguments
+ <- KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments
/ PrimaryTypeExpr (SuffixOp / FnCallArguments)*
PrimaryTypeExpr
@@ -10063,7 +10063,7 @@ FnCC
<- KEYWORD_nakedcc
/ KEYWORD_stdcallcc
/ KEYWORD_extern
- / KEYWORD_async (LARROW TypeExpr RARROW)?
+ / KEYWORD_async
ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
@@ -10168,8 +10168,6 @@ SuffixOp
/ DOTASTERISK
/ DOTQUESTIONMARK
-AsyncPrefix <- KEYWORD_async (LARROW PrefixExpr RARROW)?
-
FnCallArguments <- LPAREN ExprList RPAREN
# Ptr specific
diff --git a/src-self-hosted/ir.zig b/src-self-hosted/ir.zig
index bc7aeffdf5..df4d436b50 100644
--- a/src-self-hosted/ir.zig
+++ b/src-self-hosted/ir.zig
@@ -1181,7 +1181,6 @@ pub const Builder = struct {
ast.Node.Id.ErrorTag => return error.Unimplemented,
ast.Node.Id.AsmInput => return error.Unimplemented,
ast.Node.Id.AsmOutput => return error.Unimplemented,
- ast.Node.Id.AsyncAttribute => return error.Unimplemented,
ast.Node.Id.ParamDecl => return error.Unimplemented,
ast.Node.Id.FieldInitializer => return error.Unimplemented,
ast.Node.Id.EnumLiteral => return error.Unimplemented,
diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig
index b18397ede2..6a91b8e7bf 100644
--- a/src-self-hosted/translate_c.zig
+++ b/src-self-hosted/translate_c.zig
@@ -1037,7 +1037,7 @@ fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node) !*ast.Node.SuffixOp {
.op = ast.Node.SuffixOp.Op{
.Call = ast.Node.SuffixOp.Op.Call{
.params = ast.Node.SuffixOp.Op.Call.ParamList.init(c.a()),
- .async_attr = null,
+ .async_token = null,
},
},
.rtoken = undefined, // set after appending args
@@ -1355,7 +1355,6 @@ fn finishTransFnProto(
.var_args_token = null, // TODO this field is broken in the AST data model
.extern_export_inline_token = extern_export_inline_tok,
.cc_token = cc_tok,
- .async_attr = null,
.body_node = null,
.lib_name = null,
.align_expr = null,
diff --git a/src/parser.cpp b/src/parser.cpp
index afe5735a06..1e7e36d0bd 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -113,7 +113,6 @@ static AstNode *ast_parse_multiply_op(ParseContext *pc);
static AstNode *ast_parse_prefix_op(ParseContext *pc);
static AstNode *ast_parse_prefix_type_op(ParseContext *pc);
static AstNode *ast_parse_suffix_op(ParseContext *pc);
-static AstNode *ast_parse_async_prefix(ParseContext *pc);
static AstNode *ast_parse_fn_call_argumnets(ParseContext *pc);
static AstNode *ast_parse_array_type_start(ParseContext *pc);
static AstNode *ast_parse_ptr_type_start(ParseContext *pc);
@@ -1389,22 +1388,18 @@ static AstNode *ast_parse_error_union_expr(ParseContext *pc) {
}
// SuffixExpr
-// <- AsyncPrefix PrimaryTypeExpr SuffixOp* FnCallArguments
+// <- KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments
// / PrimaryTypeExpr (SuffixOp / FnCallArguments)*
static AstNode *ast_parse_suffix_expr(ParseContext *pc) {
- AstNode *async_call = ast_parse_async_prefix(pc);
- if (async_call != nullptr) {
+ Token *async_token = eat_token_if(pc, TokenIdKeywordAsync);
+ if (async_token != nullptr) {
if (eat_token_if(pc, TokenIdKeywordFn) != nullptr) {
// HACK: If we see the keyword `fn`, then we assume that
// we are parsing an async fn proto, and not a call.
// We therefore put back all tokens consumed by the async
// prefix...
- // HACK: This loop is not actually enough to put back all the
- // tokens. Let's hope this is fine for most code right now
- // and wait till we get the async rework for a syntax update.
- do {
- put_back_token(pc);
- } while (peek_token(pc)->id != TokenIdKeywordAsync);
+ put_back_token(pc);
+ put_back_token(pc);
return ast_parse_primary_type_expr(pc);
}
@@ -1446,10 +1441,14 @@ static AstNode *ast_parse_suffix_expr(ParseContext *pc) {
ast_invalid_token_error(pc, peek_token(pc));
assert(args->type == NodeTypeFnCallExpr);
- async_call->data.fn_call_expr.fn_ref_expr = child;
- async_call->data.fn_call_expr.params = args->data.fn_call_expr.params;
- async_call->data.fn_call_expr.is_builtin = false;
- return async_call;
+
+ AstNode *res = ast_create_node(pc, NodeTypeFnCallExpr, async_token);
+ res->data.fn_call_expr.is_async = true;
+ res->data.fn_call_expr.seen = false;
+ res->data.fn_call_expr.fn_ref_expr = child;
+ res->data.fn_call_expr.params = args->data.fn_call_expr.params;
+ res->data.fn_call_expr.is_builtin = false;
+ return res;
}
AstNode *res = ast_parse_primary_type_expr(pc);
@@ -1501,7 +1500,7 @@ static AstNode *ast_parse_suffix_expr(ParseContext *pc) {
// <- BUILTINIDENTIFIER FnCallArguments
// / CHAR_LITERAL
// / ContainerDecl
-// / DOT IDENTIFIER
+// / DOT IDENTIFIER
// / ErrorSetDecl
// / FLOAT
// / FnProto
@@ -2016,7 +2015,7 @@ static AstNode *ast_parse_link_section(ParseContext *pc) {
// <- KEYWORD_nakedcc
// / KEYWORD_stdcallcc
// / KEYWORD_extern
-// / KEYWORD_async (LARROW TypeExpr RARROW)?
+// / KEYWORD_async
static Optional ast_parse_fn_cc(ParseContext *pc) {
AstNodeFnProto res = {};
if (eat_token_if(pc, TokenIdKeywordNakedCC) != nullptr) {
@@ -2657,19 +2656,6 @@ static AstNode *ast_parse_suffix_op(ParseContext *pc) {
return nullptr;
}
-// AsyncPrefix <- KEYWORD_async (LARROW PrefixExpr RARROW)?
-static AstNode *ast_parse_async_prefix(ParseContext *pc) {
- Token *async = eat_token_if(pc, TokenIdKeywordAsync);
- if (async == nullptr)
- return nullptr;
-
- AstNode *res = ast_create_node(pc, NodeTypeFnCallExpr, async);
- res->data.fn_call_expr.is_async = true;
- res->data.fn_call_expr.seen = false;
-
- return res;
-}
-
// FnCallArguments <- LPAREN ExprList RPAREN
static AstNode *ast_parse_fn_call_argumnets(ParseContext *pc) {
Token *paren = eat_token_if(pc, TokenIdLParen);
diff --git a/std/zig/ast.zig b/std/zig/ast.zig
index 475a0e4e13..e5781da035 100644
--- a/std/zig/ast.zig
+++ b/std/zig/ast.zig
@@ -434,7 +434,6 @@ pub const Node = struct {
ErrorTag,
AsmInput,
AsmOutput,
- AsyncAttribute,
ParamDecl,
FieldInitializer,
};
@@ -838,36 +837,6 @@ pub const Node = struct {
}
};
- pub const AsyncAttribute = struct {
- base: Node,
- async_token: TokenIndex,
- allocator_type: ?*Node,
- rangle_bracket: ?TokenIndex,
-
- pub fn iterate(self: *AsyncAttribute, index: usize) ?*Node {
- var i = index;
-
- if (self.allocator_type) |allocator_type| {
- if (i < 1) return allocator_type;
- i -= 1;
- }
-
- return null;
- }
-
- pub fn firstToken(self: *const AsyncAttribute) TokenIndex {
- return self.async_token;
- }
-
- pub fn lastToken(self: *const AsyncAttribute) TokenIndex {
- if (self.rangle_bracket) |rangle_bracket| {
- return rangle_bracket;
- }
-
- return self.async_token;
- }
- };
-
pub const FnProto = struct {
base: Node,
doc_comments: ?*DocComment,
@@ -879,7 +848,6 @@ pub const Node = struct {
var_args_token: ?TokenIndex,
extern_export_inline_token: ?TokenIndex,
cc_token: ?TokenIndex,
- async_attr: ?*AsyncAttribute,
body_node: ?*Node,
lib_name: ?*Node, // populated if this is an extern declaration
align_expr: ?*Node, // populated if align(A) is present
@@ -935,7 +903,6 @@ pub const Node = struct {
pub fn firstToken(self: *const FnProto) TokenIndex {
if (self.visib_token) |visib_token| return visib_token;
- if (self.async_attr) |async_attr| return async_attr.firstToken();
if (self.extern_export_inline_token) |extern_export_inline_token| return extern_export_inline_token;
assert(self.lib_name == null);
if (self.cc_token) |cc_token| return cc_token;
@@ -1699,7 +1666,7 @@ pub const Node = struct {
pub const Call = struct {
params: ParamList,
- async_attr: ?*AsyncAttribute,
+ async_token: ?TokenIndex,
pub const ParamList = SegmentedList(*Node, 2);
};
@@ -1752,7 +1719,7 @@ pub const Node = struct {
pub fn firstToken(self: *const SuffixOp) TokenIndex {
switch (self.op) {
- .Call => |*call_info| if (call_info.async_attr) |async_attr| return async_attr.firstToken(),
+ .Call => |*call_info| if (call_info.async_token) |async_token| return async_token,
else => {},
}
return self.lhs.firstToken();
diff --git a/std/zig/parse.zig b/std/zig/parse.zig
index 077870a9ca..0a2fbb4fa1 100644
--- a/std/zig/parse.zig
+++ b/std/zig/parse.zig
@@ -277,7 +277,7 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
/// FnProto <- FnCC? KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
- const cc = try parseFnCC(arena, it, tree);
+ const cc = parseFnCC(arena, it, tree);
const fn_token = eatToken(it, .Keyword_fn) orelse {
if (cc == null) return null else return error.ParseError;
};
@@ -320,7 +320,6 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
.var_args_token = var_args_token,
.extern_export_inline_token = null,
.cc_token = null,
- .async_attr = null,
.body_node = null,
.lib_name = null,
.align_expr = align_expr,
@@ -331,7 +330,6 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
switch (kind) {
.CC => |token| fn_proto_node.cc_token = token,
.Extern => |token| fn_proto_node.extern_export_inline_token = token,
- .Async => |node| fn_proto_node.async_attr = node,
}
}
@@ -1092,10 +1090,19 @@ fn parseErrorUnionExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No
}
/// SuffixExpr
-/// <- AsyncPrefix PrimaryTypeExpr SuffixOp* FnCallArguments
+/// <- KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments
/// / PrimaryTypeExpr (SuffixOp / FnCallArguments)*
fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
- if (try parseAsyncPrefix(arena, it, tree)) |async_node| {
+ if (eatToken(it, .Keyword_async)) |async_token| {
+ if (eatToken(it, .Keyword_fn)) |token_fn| {
+ // HACK: If we see the keyword `fn`, then we assume that
+ // we are parsing an async fn proto, and not a call.
+ // We therefore put back all tokens consumed by the async
+ // prefix...
+ putBackToken(it, token_fn);
+ putBackToken(it, async_token);
+ return parsePrimaryTypeExpr(arena, it, tree);
+ }
// TODO: Implement hack for parsing `async fn ...` in ast_parse_suffix_expr
var res = try expectNode(arena, it, tree, parsePrimaryTypeExpr, AstError{
.ExpectedPrimaryTypeExpr = AstError.ExpectedPrimaryTypeExpr{ .token = it.index },
@@ -1116,7 +1123,6 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
});
return null;
};
-
const node = try arena.create(Node.SuffixOp);
node.* = Node.SuffixOp{
.base = Node{ .id = .SuffixOp },
@@ -1124,14 +1130,13 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
.op = Node.SuffixOp.Op{
.Call = Node.SuffixOp.Op.Call{
.params = params.list,
- .async_attr = async_node.cast(Node.AsyncAttribute).?,
+ .async_token = async_token,
},
},
.rtoken = params.rparen,
};
return &node.base;
}
-
if (try parsePrimaryTypeExpr(arena, it, tree)) |expr| {
var res = expr;
@@ -1153,7 +1158,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
.op = Node.SuffixOp.Op{
.Call = Node.SuffixOp.Op.Call{
.params = params.list,
- .async_attr = null,
+ .async_token = null,
},
},
.rtoken = params.rparen,
@@ -1653,36 +1658,18 @@ fn parseLinkSection(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
/// <- KEYWORD_nakedcc
/// / KEYWORD_stdcallcc
/// / KEYWORD_extern
-/// / KEYWORD_async (LARROW TypeExpr RARROW)?
-fn parseFnCC(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?FnCC {
+/// / KEYWORD_async
+fn parseFnCC(arena: *Allocator, it: *TokenIterator, tree: *Tree) ?FnCC {
if (eatToken(it, .Keyword_nakedcc)) |token| return FnCC{ .CC = token };
if (eatToken(it, .Keyword_stdcallcc)) |token| return FnCC{ .CC = token };
if (eatToken(it, .Keyword_extern)) |token| return FnCC{ .Extern = token };
- if (eatToken(it, .Keyword_async)) |token| {
- const node = try arena.create(Node.AsyncAttribute);
- node.* = Node.AsyncAttribute{
- .base = Node{ .id = .AsyncAttribute },
- .async_token = token,
- .allocator_type = null,
- .rangle_bracket = null,
- };
- if (eatToken(it, .AngleBracketLeft)) |_| {
- const type_expr = try expectNode(arena, it, tree, parseTypeExpr, AstError{
- .ExpectedTypeExpr = AstError.ExpectedTypeExpr{ .token = it.index },
- });
- const rarrow = try expectToken(it, tree, .AngleBracketRight);
- node.allocator_type = type_expr;
- node.rangle_bracket = rarrow;
- }
- return FnCC{ .Async = node };
- }
+ if (eatToken(it, .Keyword_async)) |token| return FnCC{ .CC = token };
return null;
}
const FnCC = union(enum) {
CC: TokenIndex,
Extern: TokenIndex,
- Async: *Node.AsyncAttribute,
};
/// ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
@@ -2409,28 +2396,6 @@ fn parseSuffixOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
return &node.base;
}
-/// AsyncPrefix <- KEYWORD_async (LARROW PrefixExpr RARROW)?
-fn parseAsyncPrefix(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
- const async_token = eatToken(it, .Keyword_async) orelse return null;
- var rangle_bracket: ?TokenIndex = null;
- const expr_node = if (eatToken(it, .AngleBracketLeft)) |_| blk: {
- const prefix_expr = try expectNode(arena, it, tree, parsePrefixExpr, AstError{
- .ExpectedPrefixExpr = AstError.ExpectedPrefixExpr{ .token = it.index },
- });
- rangle_bracket = try expectToken(it, tree, .AngleBracketRight);
- break :blk prefix_expr;
- } else null;
-
- const node = try arena.create(Node.AsyncAttribute);
- node.* = Node.AsyncAttribute{
- .base = Node{ .id = .AsyncAttribute },
- .async_token = async_token,
- .allocator_type = expr_node,
- .rangle_bracket = rangle_bracket,
- };
- return &node.base;
-}
-
/// FnCallArguments <- LPAREN ExprList RPAREN
/// ExprList <- (Expr COMMA)* Expr?
fn parseFnCallArguments(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?AnnotatedParamList {
diff --git a/std/zig/parser_test.zig b/std/zig/parser_test.zig
index c5c740353e..7d6456ed0a 100644
--- a/std/zig/parser_test.zig
+++ b/std/zig/parser_test.zig
@@ -210,7 +210,7 @@ test "zig fmt: spaces around slice operator" {
test "zig fmt: async call in if condition" {
try testCanonical(
\\comptime {
- \\ if (async b()) {
+ \\ if (async b()) {
\\ a();
\\ }
\\}
@@ -1118,7 +1118,7 @@ test "zig fmt: first line comment in struct initializer" {
\\pub async fn acquire(self: *Self) HeldLock {
\\ return HeldLock{
\\ // guaranteed allocation elision
- \\ .held = await (async self.lock.acquire() catch unreachable),
+ \\ .held = self.lock.acquire(),
\\ .value = &self.private_data,
\\ };
\\}
diff --git a/std/zig/render.zig b/std/zig/render.zig
index 2e034142c2..035526ed11 100644
--- a/std/zig/render.zig
+++ b/std/zig/render.zig
@@ -284,20 +284,6 @@ fn renderExpression(
return renderExpression(allocator, stream, tree, indent, start_col, comptime_node.expr, space);
},
- ast.Node.Id.AsyncAttribute => {
- const async_attr = @fieldParentPtr(ast.Node.AsyncAttribute, "base", base);
-
- if (async_attr.allocator_type) |allocator_type| {
- try renderToken(tree, stream, async_attr.async_token, indent, start_col, Space.None); // async
-
- try renderToken(tree, stream, tree.nextToken(async_attr.async_token), indent, start_col, Space.None); // <
- try renderExpression(allocator, stream, tree, indent, start_col, allocator_type, Space.None); // allocator
- return renderToken(tree, stream, tree.nextToken(allocator_type.lastToken()), indent, start_col, space); // >
- } else {
- return renderToken(tree, stream, async_attr.async_token, indent, start_col, space); // async
- }
- },
-
ast.Node.Id.Suspend => {
const suspend_node = @fieldParentPtr(ast.Node.Suspend, "base", base);
@@ -459,8 +445,8 @@ fn renderExpression(
switch (suffix_op.op) {
@TagType(ast.Node.SuffixOp.Op).Call => |*call_info| {
- if (call_info.async_attr) |async_attr| {
- try renderExpression(allocator, stream, tree, indent, start_col, &async_attr.base, Space.Space);
+ if (call_info.async_token) |async_token| {
+ try renderToken(tree, stream, async_token, indent, start_col, Space.Space);
}
try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
@@ -1121,10 +1107,6 @@ fn renderExpression(
try renderToken(tree, stream, cc_token, indent, start_col, Space.Space); // stdcallcc
}
- if (fn_proto.async_attr) |async_attr| {
- try renderExpression(allocator, stream, tree, indent, start_col, &async_attr.base, Space.Space);
- }
-
const lparen = if (fn_proto.name_token) |name_token| blk: {
try renderToken(tree, stream, fn_proto.fn_token, indent, start_col, Space.Space); // fn
try renderToken(tree, stream, name_token, indent, start_col, Space.None); // name
--
cgit v1.2.3