Removal of "or_else jump". Fixes to defer & macros/blocks, optimized failable return. @noscope macros removed. Disallow meaningless defer.

Correctly show error on return or rethrow inside of a defer. Fix copying an access expression. Removing scoped expr.
This commit is contained in:
Christoffer Lerno
2022-03-22 21:21:41 +01:00
committed by Christoffer Lerno
parent bbfc2fc8ab
commit b31629c5e8
31 changed files with 858 additions and 849 deletions

View File

@@ -0,0 +1,40 @@
// #target: x64-darwin
module foo;
extern fn void printf(char*,...);
fn void main()
{
defer printf("On exit\n");
{|
defer printf("Baz\n");
defer {|
defer printf("Hello!\n");
defer printf("1\n");
if (true) return 12;
defer printf("2\n");
return 34;
|};
|};
defer printf("On 2\n");
}
/* #expect: foo.ll
define void @foo.main() #0 {
entry:
%blockret = alloca i32, align 4
br label %if.then
if.then: ; preds = %entry
call void (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0))
call void (i8*, ...) @printf(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.1, i32 0, i32 0))
store i32 12, i32* %blockret, align 4
br label %expr_block.exit
expr_block.exit: ; preds = %if.then
call void (i8*, ...) @printf(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.5, i32 0, i32 0))
call void (i8*, ...) @printf(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.6, i32 0, i32 0))
call void (i8*, ...) @printf(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.7, i32 0, i32 0))
ret void
}

View File

@@ -0,0 +1,41 @@
fn void test1()
{
while (1) defer foo(); // #error: Looping over a raw 'defer'
}
fn void test1a()
{
while (1) { defer foo(); }
}
fn void test2()
{
if (1) defer foo(); // #error: An 'if' statement may not be followed by a raw 'defer'
}
fn void test2a()
{
if (1) { defer foo(); }
}
fn void test3()
{
defer defer foo(); // #error: A defer may not have a body consisting of a raw 'defer'
}
fn void test3a()
{
defer { defer foo(); }
}
fn void test4()
{
for (;;) defer foo(); // #error: Looping over a raw 'defer'
}
fn void test4a()
{
for(;;) { defer foo(); }
}
fn void foo() {}

View File

@@ -0,0 +1,14 @@
fn int! foo()
{ return 1; }
fn int! bar()
{
defer {
{|
foo()?;
|};
}
defer foo()?; // #error: Returns are not allowed inside of defers.
return 1;
}

View File

@@ -0,0 +1,10 @@
fn int! bar()
{
defer {
{|
return 4;
|};
}
defer return 3; // #error: Return is not allowed inside of a defer
return 1;
}