From e22afe5424a2c869cd2b321c70cc23dcec9433b7 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Sun, 13 Aug 2023 18:15:20 +0200 Subject: [PATCH] Allow "if (try foo())"." --- src/compiler/llvm_codegen_expr.c | 11 ++++++- src/compiler/sema_stmts.c | 8 +++-- src/version.h | 2 +- test/test_suite/errors/try_expr.c3t | 49 +++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 test/test_suite/errors/try_expr.c3t diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index 6d24ada74..b1a52c035 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -6168,7 +6168,16 @@ static inline void llvm_emit_try_unwrap(GenContext *c, BEValue *value, Expr *exp BEValue addr; if (expr->try_unwrap_expr.assign_existing) { - llvm_emit_expr(c, &addr, expr->try_unwrap_expr.lhs); + Expr *lhs = expr->try_unwrap_expr.lhs; + if (lhs) + { + llvm_emit_expr(c, &addr, lhs); + } + else + { + llvm_emit_try_assign_try_catch(c, true, value, NULL, NULL, expr->try_unwrap_expr.optional); + return; + } } else { diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index 271a09558..f04122b3a 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -534,10 +534,14 @@ static inline bool sema_analyse_try_unwrap(SemaContext *context, Expr *expr) if (!optional) { if (!sema_analyse_expr(context, ident)) return false; + // The `try foo()` case. if (ident->expr_kind != EXPR_IDENTIFIER) { - SEMA_ERROR(ident, "Only single identifiers may be unwrapped using 'try var', maybe you wanted 'try (expr)' instead?"); - return false; + expr->try_unwrap_expr.optional = ident; + expr->try_unwrap_expr.lhs = NULL; + expr->try_unwrap_expr.assign_existing = true; + expr->type = type_bool; + return true; } Decl *decl = ident->identifier_expr.decl; if (decl->decl_kind != DECL_VAR) diff --git a/src/version.h b/src/version.h index 07bbc889e..0111e7739 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "0.4.605" \ No newline at end of file +#define COMPILER_VERSION "0.4.606" \ No newline at end of file diff --git a/test/test_suite/errors/try_expr.c3t b/test/test_suite/errors/try_expr.c3t new file mode 100644 index 000000000..9ca8de6f2 --- /dev/null +++ b/test/test_suite/errors/try_expr.c3t @@ -0,0 +1,49 @@ +// #target: macos-x64 +module foo; +import std::io; + +fn void main() +{ + int a; + if (try foo()) + { + a--; + } + else + { + a++; + } +} + +fn void! foo() {} + +/* #expect: foo.ll + +define void @foo.main() #0 { +entry: + %a = alloca i32, align 4 + store i32 0, ptr %a, align 4 + %0 = call i64 @foo.foo() + %not_err = icmp eq i64 %0, 0 + %1 = call i1 @llvm.expect.i1(i1 %not_err, i1 true) + br i1 %1, label %after_check, label %catch_landing +after_check: ; preds = %entry + br label %phi_try_catch +catch_landing: ; preds = %entry + br label %phi_try_catch +phi_try_catch: ; preds = %catch_landing, %after_check + %val = phi i1 [ true, %after_check ], [ false, %catch_landing ] + br i1 %val, label %if.then, label %if.else +if.then: ; preds = %phi_try_catch + %2 = load i32, ptr %a, align 4 + %sub = sub i32 %2, 1 + store i32 %sub, ptr %a, align 4 + br label %if.exit +if.else: ; preds = %phi_try_catch + %3 = load i32, ptr %a, align 4 + %add = add i32 %3, 1 + store i32 %add, ptr %a, align 4 + br label %if.exit +if.exit: ; preds = %if.else, %if.then + ret void +}