summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c1
-rw-r--r--test.toc12
-rw-r--r--tests/defer.toc12
-rw-r--r--tests/defer_expected2
-rw-r--r--types.c8
5 files changed, 34 insertions, 1 deletions
diff --git a/main.c b/main.c
index b24c794..3134bca 100644
--- a/main.c
+++ b/main.c
@@ -8,7 +8,6 @@
/*
TODO:
-make sure you can't return a #C() (because of the current defer system)
switch to:
static void
foo() {
diff --git a/test.toc b/test.toc
index 28e639e..1ecc9ce 100644
--- a/test.toc
+++ b/test.toc
@@ -1,6 +1,18 @@
#include "std/io.toc", io;
+plusone ::= fn(n : int) x := n {
+ defer x += 1;
+}
+
+same ::= fn(n : int) int {
+ x := n;
+ defer x += 1;
+ x
+}
+
main ::= fn() {
+ io.puti(plusone(3));
+ io.puti(same(3));
defer io.puts("deferred from main()");
for i := 1..10 {
defer io.puts("deferred from for");
diff --git a/tests/defer.toc b/tests/defer.toc
index 77a4c4e..32165e7 100644
--- a/tests/defer.toc
+++ b/tests/defer.toc
@@ -1,6 +1,18 @@
#include "io.toc", io;
+plusone ::= fn(n : int) x := n {
+ defer x += 1;
+}
+
+same ::= fn(n : int) int {
+ x := n;
+ defer x += 1;
+ x
+}
+
main ::= fn() {
+ io.puti(plusone(3));
+ io.puti(same(3));
defer io.puts("deferred from main()");
for i := 1..10 {
defer io.puts("deferred from for");
diff --git a/tests/defer_expected b/tests/defer_expected
index 0a6daa7..99b45e1 100644
--- a/tests/defer_expected
+++ b/tests/defer_expected
@@ -1,3 +1,5 @@
+4
+3
1
deferred from for
2
diff --git a/types.c b/types.c
index f2b7db1..8f64879 100644
--- a/types.c
+++ b/types.c
@@ -1074,6 +1074,14 @@ static Status types_fn(Typer *tr, FnExpr *f, Type *t, Instance *instance) {
success = false;
goto ret;
}
+ if (ret_expr->type.kind == TYPE_UNKNOWN) {
+ /* maybe it's just unknown because something messed up (like typing another function),
+ and ??? is a placeholder */
+ if (!tr->err_ctx->have_errored) {
+ err_print(ret_expr->where, "Can't determine type of return value. Try assigning it to a variable before returning it.");
+ return false;
+ }
+ }
} else if (ret_type->kind != TYPE_VOID && !has_named_ret_vals) {
Statement *stmts = f->body.stmts;
if (arr_len(stmts)) {