From 60945ffe58cb8329c862636e238bcdd81403ce2e Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Mon, 5 Aug 2024 19:52:34 +0200 Subject: [PATCH] Fix of tests. --- src/compiler/sema_stmts.c | 10 ++- test/test_suite/errors/try_assign.c3t | 74 +++++++++---------- .../errors/try_with_chained_unwrap.c3t | 1 - .../errors/try_with_chained_unwrap_errors.c3 | 18 ++--- 4 files changed, 53 insertions(+), 50 deletions(-) diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index c4f5f1718..c0c5a9d2a 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -747,11 +747,17 @@ static inline bool sema_analyse_try_unwrap(SemaContext *context, Expr *expr) // 3a. If we had a variable type, then our expression must be an identifier. if (ident->expr_kind != EXPR_IDENTIFIER) RETURN_SEMA_ERROR(ident, "A variable name was expected here."); - assert(ident->resolve_status != RESOLVE_DONE); if (ident->identifier_expr.path) RETURN_SEMA_ERROR(ident->identifier_expr.path, "The variable may not have a path."); - if (ident->identifier_expr.is_const) RETURN_SEMA_ERROR(ident, "Expected a variable starting with a lower case letter."); + const char *ident_name = ident->identifier_expr.ident; + + // Special check for `if (try a = a)` + if (optional->expr_kind == EXPR_IDENTIFIER && optional->resolve_status == RESOLVE_NOT_DONE + && !optional->identifier_expr.path && optional->identifier_expr.ident == ident_name) + { + RETURN_SEMA_ERROR(ident, "If you want to unwrap the same variable, use 'if (try %s)' { ... } instead.", ident_name); + } // 3b. Evaluate the expression if (!sema_analyse_expr(context, optional)) return false; diff --git a/test/test_suite/errors/try_assign.c3t b/test/test_suite/errors/try_assign.c3t index d8770d959..98654f962 100644 --- a/test/test_suite/errors/try_assign.c3t +++ b/test/test_suite/errors/try_assign.c3t @@ -6,10 +6,8 @@ extern fn int printf(char* fmt, ...); fn void main() { - int x = 123; int! z = 234; int! w; - int gh = 1; if (try x = z && try gh = w) { printf("Success %d && %d!\n", x, gh); @@ -28,19 +26,19 @@ fn void main() define void @try_assign.main() #0 { entry: - %x = alloca i32, align 4 %z = alloca i32, align 4 %z.f = alloca i64, align 8 %w = alloca i32, align 4 %w.f = alloca i64, align 8 + %x = alloca i32, align 4 %gh = alloca i32, align 4 + %x8 = alloca i32, align 4 %e = alloca i64, align 8 - store i32 123, ptr %x, align 4 store i32 234, ptr %z, align 4 store i64 0, ptr %z.f, align 8 store i64 0, ptr %w.f, align 8 store i32 0, ptr %w, align 4 - store i32 1, ptr %gh, align 4 + store i32 0, ptr %x, align 4 %optval = load i64, ptr %z.f, align 8 %not_err = icmp eq i64 %optval, 0 %0 = call i1 @llvm.expect.i1(i1 %not_err, i1 true) @@ -59,6 +57,7 @@ phi_try_catch: ; preds = %catch_landing, %aft br i1 %val, label %chain_next, label %fail_chain chain_next: ; preds = %phi_try_catch + store i32 0, ptr %gh, align 4 %optval1 = load i64, ptr %w.f, align 8 %not_err2 = icmp eq i64 %optval1, 0 %2 = call i1 @llvm.expect.i1(i1 %not_err2, i1 true) @@ -93,62 +92,63 @@ if.then: ; preds = %end_chain br label %if.exit if.exit: ; preds = %if.then, %end_chain - %optval8 = load i64, ptr %z.f, align 8 - %not_err9 = icmp eq i64 %optval8, 0 - %7 = call i1 @llvm.expect.i1(i1 %not_err9, i1 true) - br i1 %7, label %after_check10, label %catch_landing14 + store i32 0, ptr %x8, align 4 + %optval9 = load i64, ptr %z.f, align 8 + %not_err10 = icmp eq i64 %optval9, 0 + %7 = call i1 @llvm.expect.i1(i1 %not_err10, i1 true) + br i1 %7, label %after_check11, label %catch_landing15 -after_check10: ; preds = %if.exit +after_check11: ; preds = %if.exit %8 = load i32, ptr %z, align 4 - %optval11 = load i64, ptr %w.f, align 8 - %not_err12 = icmp eq i64 %optval11, 0 - %9 = call i1 @llvm.expect.i1(i1 %not_err12, i1 true) - br i1 %9, label %after_check13, label %catch_landing14 + %optval12 = load i64, ptr %w.f, align 8 + %not_err13 = icmp eq i64 %optval12, 0 + %9 = call i1 @llvm.expect.i1(i1 %not_err13, i1 true) + br i1 %9, label %after_check14, label %catch_landing15 -after_check13: ; preds = %after_check10 +after_check14: ; preds = %after_check11 %10 = load i32, ptr %w, align 4 %add = add i32 %8, %10 - store i32 %add, ptr %x, align 4 - br label %phi_try_catch15 + store i32 %add, ptr %x8, align 4 + br label %phi_try_catch16 -catch_landing14: ; preds = %after_check10, %if.exit - br label %phi_try_catch15 +catch_landing15: ; preds = %after_check11, %if.exit + br label %phi_try_catch16 -phi_try_catch15: ; preds = %catch_landing14, %after_check13 - %val16 = phi i1 [ true, %after_check13 ], [ false, %catch_landing14 ] - br i1 %val16, label %if.then17, label %if.exit18 +phi_try_catch16: ; preds = %catch_landing15, %after_check14 + %val17 = phi i1 [ true, %after_check14 ], [ false, %catch_landing15 ] + br i1 %val17, label %if.then18, label %if.exit19 -if.then17: ; preds = %phi_try_catch15 +if.then18: ; preds = %phi_try_catch16 %11 = call i32 (ptr, ...) @printf(ptr @.str.1) - br label %if.exit18 + br label %if.exit19 -if.exit18: ; preds = %if.then17, %phi_try_catch15 +if.exit19: ; preds = %if.then18, %phi_try_catch16 br label %testblock -testblock: ; preds = %if.exit18 - %optval19 = load i64, ptr %z.f, align 8 - %not_err20 = icmp eq i64 %optval19, 0 - %12 = call i1 @llvm.expect.i1(i1 %not_err20, i1 true) - br i1 %12, label %after_check21, label %assign_optional +testblock: ; preds = %if.exit19 + %optval20 = load i64, ptr %z.f, align 8 + %not_err21 = icmp eq i64 %optval20, 0 + %12 = call i1 @llvm.expect.i1(i1 %not_err21, i1 true) + br i1 %12, label %after_check22, label %assign_optional assign_optional: ; preds = %testblock - store i64 %optval19, ptr %e, align 8 + store i64 %optval20, ptr %e, align 8 br label %end_block -after_check21: ; preds = %testblock +after_check22: ; preds = %testblock store i64 0, ptr %e, align 8 br label %end_block -end_block: ; preds = %after_check21, %assign_optional +end_block: ; preds = %after_check22, %assign_optional %13 = load i64, ptr %e, align 8 %neq = icmp ne i64 %13, 0 - br i1 %neq, label %if.then22, label %if.exit23 + br i1 %neq, label %if.then23, label %if.exit24 -if.then22: ; preds = %end_block +if.then23: ; preds = %end_block %14 = call i32 (ptr, ...) @printf(ptr @.str.2) - br label %if.exit23 + br label %if.exit24 -if.exit23: ; preds = %if.then22, %end_block +if.exit24: ; preds = %if.then23, %end_block ret void } diff --git a/test/test_suite/errors/try_with_chained_unwrap.c3t b/test/test_suite/errors/try_with_chained_unwrap.c3t index 1923dae57..5a34b82b8 100644 --- a/test/test_suite/errors/try_with_chained_unwrap.c3t +++ b/test/test_suite/errors/try_with_chained_unwrap.c3t @@ -7,7 +7,6 @@ extern fn int printf(char* fmt, ...); fn void main() { - int val; if (try val = atoi(readLine())) { printf("You typed the number %d\n", val); diff --git a/test/test_suite/errors/try_with_chained_unwrap_errors.c3 b/test/test_suite/errors/try_with_chained_unwrap_errors.c3 index c57acffc1..29b71f47d 100644 --- a/test/test_suite/errors/try_with_chained_unwrap_errors.c3 +++ b/test/test_suite/errors/try_with_chained_unwrap_errors.c3 @@ -7,9 +7,8 @@ fn void test() fn void test2() { int! a; - int b; if (try b = a) {} - if (try test2 = a) {} // #error: You cannot assign a value to a function + if (try test2 = a) {} } const int BAZ = 1; @@ -19,7 +18,7 @@ fn void test3() int! a; int b; - if (try BAZ = a) {} // #error: You cannot assign to a constant + if (try BAZ = a) {} // #error: lower case } @@ -27,7 +26,6 @@ fn void test4() { int! a; - int b; if (try b = 1) {} // #error: remove 'try' } @@ -36,7 +34,7 @@ fn void test5() int! a; int b; - if (try a = a) {} // #error: you use 'try' without '=' + if (try a = a) {} // #error: if (try a) } fn void test6() @@ -45,7 +43,7 @@ fn void test6() int! a; int b; int*! x; - if (try *x = a) {} // #error: You cannot assign to a dereferenced optional. + if (try *x = a) {} // #error: variable name } @@ -60,10 +58,10 @@ fn void test7() fn void test8() { int! a; - int b; - if (b == 0, try b = a && try b = a && b > 0) {} - if (try b = a && try b = a && b > 0) {} - if (try c = a && try c = a) { c++; } + int e; + if (e == 0, try c = a && try d = a && e > 0) {} + if (try b = a && try c = a && e > 0) {} + if (try c = a && try d = a) { c++; } } fn void test9()