diff --git a/releasenotes.md b/releasenotes.md index 5ef5accd1..1090eae55 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -40,6 +40,7 @@ - Empty expression block would crash compiler with debug on #1554. - Improve infer conversions on constants, e.g. `ZString a = foo ? "a" : "b";` #1561 - Show error when declarations do not start with `fn` in interfaces. #1565 +- `if (try foo)` was handled incorrectly inside a defer. ### Stdlib changes - Remove unintended print of `char[]` as String diff --git a/src/compiler/copying.c b/src/compiler/copying.c index ea4165c19..ac2a4c787 100644 --- a/src/compiler/copying.c +++ b/src/compiler/copying.c @@ -372,7 +372,14 @@ Expr *copy_expr(CopyStruct *c, Expr *source_expr) } else { - MACRO_COPY_DECL(expr->try_unwrap_expr.decl); + if (expr->try_unwrap_expr.optional) + { + MACRO_COPY_DECL(expr->try_unwrap_expr.decl); + } + else + { + fixup_decl(c, &expr->try_unwrap_expr.decl); + } } } return expr; diff --git a/test/test_suite/statements/defer_if_try_copy.c3t b/test/test_suite/statements/defer_if_try_copy.c3t new file mode 100644 index 000000000..74c7dc7dd --- /dev/null +++ b/test/test_suite/statements/defer_if_try_copy.c3t @@ -0,0 +1,36 @@ +// #target: macos-x64 +module foo; +import std; +fn int main() +{ + int! cmd = 3; + defer + { + if (try cmd) { io::printfn("HO! %s", cmd); } + } + return 0; +} +/* #expect: foo.ll + +define i32 @main() #0 { +entry: + %cmd = alloca i32, align 4 + %cmd.f = alloca i64, align 8 + %varargslots = alloca [1 x %any], align 16 + %retparam = alloca i64, align 8 + store i32 3, ptr %cmd, align 4 + store i64 0, ptr %cmd.f, align 8 + %load.err = load i64, ptr %cmd.f, align 8 + %result = icmp eq i64 %load.err, 0 + br i1 %result, label %if.then, label %if.exit + +if.then: ; preds = %entry + %0 = insertvalue %any undef, ptr %cmd, 0 + %1 = insertvalue %any %0, i64 ptrtoint (ptr @"$ct.int" to i64), 1 + store %any %1, ptr %varargslots, align 16 + %2 = call i64 @std.io.printfn(ptr %retparam, ptr @.str, i64 6, ptr %varargslots, i64 1) + br label %if.exit + +if.exit: ; preds = %if.then, %entry + ret i32 0 +}