diff --git a/releasenotes.md b/releasenotes.md index dc885dd02..3384c490b 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -22,6 +22,7 @@ - Improve `@param` parse errors #1777 - Improved `#foo` resolution inside of the compiler. - Deprecated '&' macro arguments. +- Deprecate `fn void! main() type main functions. ### Fixes - Fix case trying to initialize a `char[*]*` from a String. diff --git a/resources/examples/base64.c3 b/resources/examples/base64.c3 index 9a935d886..e856a9735 100644 --- a/resources/examples/base64.c3 +++ b/resources/examples/base64.c3 @@ -120,7 +120,7 @@ fn int! decode(String in, char* out, int* invalid_char_index = null) extern fn void printf(char *fmt, ...); -fn void! main() +fn void main() { char *helloworld = "Hello World\n"; char[1000] buffer; @@ -128,7 +128,7 @@ fn void! main() printf("Result: %s\n", &buffer); char *to_decode = "aGVsbG8gd29ybGRcMA=="; char[*] result = b64"aGVsbG8gd29ybGRcMA=="; - decode((String)to_decode[0..19], &buffer)!; + decode((String)to_decode[0..19], &buffer)!!; printf("Result: %s\n", &buffer); printf("Result direct: %.*s\n", 13, &result); } \ No newline at end of file diff --git a/resources/examples/brainfk.c3 b/resources/examples/brainfk.c3 index a948dd74e..6f3f89fd3 100644 --- a/resources/examples/brainfk.c3 +++ b/resources/examples/brainfk.c3 @@ -73,7 +73,7 @@ fn void! brainf(String program) } } } -fn void! main() +fn void main() { String program = ` ++++[>+++++<-]>[<+++++>-]+<+[ @@ -81,5 +81,5 @@ fn void! main() >>>+[[-]++++++>>>]<<<[[<++++++++<++>>-]+<.<[>----<-]<] <<[>>>>>[>>>[-]+++++++++<[>-<-]+++++++++>[-[<->-]+[<<<]]<[>+<-]>]<<-]<<- ]`; - brainf(program)!; + brainf(program)!!; } \ No newline at end of file diff --git a/resources/examples/contextfree/cleanup.c3 b/resources/examples/contextfree/cleanup.c3 index bdb1c7ea6..1d2b96618 100644 --- a/resources/examples/contextfree/cleanup.c3 +++ b/resources/examples/contextfree/cleanup.c3 @@ -44,9 +44,9 @@ fn Resource! prep_out(String out_name, String[] prep_names) return writer; } -fn void! main() +fn void main() { - Resource writer = prep_out("out", String[] { "a", "b"})!; + Resource writer = prep_out("out", String[] { "a", "b"}); defer writer.deinit(); io::printn("use out"); } \ No newline at end of file diff --git a/resources/examples/contextfree/guess_number.c3 b/resources/examples/contextfree/guess_number.c3 index fb77eed39..b53ae70b8 100644 --- a/resources/examples/contextfree/guess_number.c3 +++ b/resources/examples/contextfree/guess_number.c3 @@ -67,7 +67,7 @@ fn void Game.update(Game *game, int guess) game.guesses++; } -fn void! main() +fn void main() { int high = 100; int answer = rand(high) + 1; diff --git a/resources/examples/fannkuch-redux2.c3 b/resources/examples/fannkuch-redux2.c3 index b561c833d..a6c5b43c6 100644 --- a/resources/examples/fannkuch-redux2.c3 +++ b/resources/examples/fannkuch-redux2.c3 @@ -63,7 +63,7 @@ fn int fannkuchredux(int n) } } -fn void! main(String[] argv) +fn void main(String[] argv) { int n = argv.len > 1 ? argv[1].to_int()!! : 7; io::printf("Pfannkuchen(%d) = %d\n", n, fannkuchredux(n)); diff --git a/resources/examples/load_world.c3 b/resources/examples/load_world.c3 index 09bd5f063..085bc919e 100644 --- a/resources/examples/load_world.c3 +++ b/resources/examples/load_world.c3 @@ -1,11 +1,11 @@ module load_world; import std::io; -fn void! main() +fn void main() { - File f = file::open("examples/hello_world.txt", "rb")!; + File f = file::open("examples/hello_world.txt", "rb")!!; defer f.close()!!; while (!f.eof()) { - @pool() { io::printn(io::treadline(&f)!); }; + @pool() { io::printn(io::treadline(&f)!!); }; } } \ No newline at end of file diff --git a/resources/examples/plus_minus.c3 b/resources/examples/plus_minus.c3 index 665b6cf7e..6dc65190f 100644 --- a/resources/examples/plus_minus.c3 +++ b/resources/examples/plus_minus.c3 @@ -10,10 +10,10 @@ fault TokenResult // While we could have written this with libc // the C way, let's showcase some features added to C3. -fn void! main(String[] args) +fn void main(String[] args) { // Grab a string from stdin - String s = io::readline()!; + String s = io::readline()!!; // Delete it at scope end [defer] defer s.free(); diff --git a/resources/examples/process.c3 b/resources/examples/process.c3 index e633ebb1f..532beeb3e 100644 --- a/resources/examples/process.c3 +++ b/resources/examples/process.c3 @@ -2,11 +2,11 @@ module test; import std::os::process; import std::io; -fn void! main() +fn void main() { String command = env::WIN32 ? "dir" : "ls"; SubProcess x = process::create({ command }, { .search_user_path = true })!!; - x.join()!; + x.join()!!; InStream stream = &&x.stdout(); while (try char b = stream.read_byte()) { diff --git a/src/compiler/ast.c b/src/compiler/ast.c index 8552cb084..5b7cf961f 100644 --- a/src/compiler/ast.c +++ b/src/compiler/ast.c @@ -147,7 +147,7 @@ const char *decl_to_a_name(Decl *decl) case VARDECL_PARAM_CT: return "a compile time parameter"; case VARDECL_PARAM_CT_TYPE: return "a compile time type parameter"; case VARDECL_PARAM_EXPR: return "a expression parameter"; - case VARDECL_PARAM_REF: return "a ref parameter"; + case VARDECL_PARAM_REF: return "a ref parameter"; // DEPRECATED case VARDECL_REWRAPPED: UNREACHABLE case VARDECL_UNWRAPPED: return "an unwrapped variable"; } @@ -373,7 +373,7 @@ bool decl_is_global(Decl *ident) case VARDECL_PARAM: case VARDECL_MEMBER: case VARDECL_BITMEMBER: - case VARDECL_PARAM_REF: + case VARDECL_PARAM_REF: // DEPRECATED case VARDECL_PARAM_EXPR: case VARDECL_UNWRAPPED: case VARDECL_ERASE: diff --git a/src/compiler/c_codegen.c b/src/compiler/c_codegen.c index 92f2ec908..8af3f5e66 100644 --- a/src/compiler/c_codegen.c +++ b/src/compiler/c_codegen.c @@ -634,7 +634,7 @@ static void c_emit_local_decl(GenContext *c, Decl *decl, CValue *value) case VARDECL_BITMEMBER: UNREACHABLE; case VARDECL_PARAM: - case VARDECL_PARAM_REF: + case VARDECL_PARAM_REF: // DEPRECATED { PRINT("/* LOCAL DECL */\n"); /* diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index cff77f3bf..5397c17a5 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -3980,7 +3980,7 @@ static inline bool decl_is_var_local(Decl *decl) || kind == VARDECL_LOCAL || kind == VARDECL_LOCAL_CT_TYPE || kind == VARDECL_LOCAL_CT - || kind == VARDECL_PARAM_REF + || kind == VARDECL_PARAM_REF // DEPRECATED || kind == VARDECL_PARAM_EXPR || kind == VARDECL_BITMEMBER || kind == VARDECL_MEMBER; diff --git a/src/compiler/expr.c b/src/compiler/expr.c index 22ac107c0..2d456e3a1 100644 --- a/src/compiler/expr.c +++ b/src/compiler/expr.c @@ -102,7 +102,7 @@ bool expr_may_addr(Expr *expr) case VARDECL_LOCAL: case VARDECL_GLOBAL: case VARDECL_PARAM: - case VARDECL_PARAM_REF: + case VARDECL_PARAM_REF: // DEPRECATED case VARDECL_CONST: return true; case VARDECL_MEMBER: @@ -462,7 +462,7 @@ static inline bool expr_unary_addr_is_constant_eval(Expr *expr) case VARDECL_BITMEMBER: case VARDECL_PARAM_CT: case VARDECL_PARAM_CT_TYPE: - case VARDECL_PARAM_REF: + case VARDECL_PARAM_REF: // DEPRECATED case VARDECL_PARAM_EXPR: case VARDECL_LOCAL_CT: case VARDECL_LOCAL_CT_TYPE: diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index 60e25ec2e..22794bb38 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -6142,7 +6142,7 @@ static inline void llvm_emit_macro_block(GenContext *c, BEValue *be_value, Expr case VARDECL_PARAM_CT_TYPE: case VARDECL_PARAM_EXPR: continue; - case VARDECL_PARAM_REF: + case VARDECL_PARAM_REF: // DEPRECATED case VARDECL_PARAM: break; } diff --git a/src/compiler/llvm_codegen_stmt.c b/src/compiler/llvm_codegen_stmt.c index 42773304b..9cdf0268b 100644 --- a/src/compiler/llvm_codegen_stmt.c +++ b/src/compiler/llvm_codegen_stmt.c @@ -82,8 +82,8 @@ void llvm_emit_local_decl(GenContext *c, Decl *decl, BEValue *value) case VARDECL_MEMBER: case VARDECL_BITMEMBER: UNREACHABLE; + case VARDECL_PARAM_REF: // DEPRECATED case VARDECL_PARAM: - case VARDECL_PARAM_REF: { Expr *init_expr = decl->var.init_expr; llvm_emit_expr(c, value, init_expr); diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index ea631f14b..14accfdfa 100755 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -3423,11 +3423,12 @@ static inline bool sema_analyse_main_function(SemaContext *context, Decl *decl) { if (rtype->optional->type_kind != TYPE_VOID) { - SEMA_ERROR(rtype_info, "The return type of 'main' cannot be an optional, unless it is 'void!'."); + RETURN_SEMA_ERROR(rtype_info, "The return type of 'main' cannot be an optional, unless it is 'void!'."); return false; } is_int_return = false; is_err_return = true; + SEMA_DEPRECATED(rtype_info, "Main functions with 'void!' returns is deprecated, use 'int' or 'void' instead."); } if (type_is_void(rtype)) is_int_return = false; @@ -3669,16 +3670,20 @@ INLINE bool sema_analyse_macro_body(SemaContext *context, Decl **body_parameters VarDeclKind kind = param->var.kind; switch (kind) { - case VARDECL_PARAM: - case VARDECL_PARAM_EXPR: - case VARDECL_PARAM_CT: case VARDECL_PARAM_REF: - case VARDECL_PARAM_CT_TYPE: + // DEPRECATED if (!type_info) break; if (!sema_resolve_type_info(context, type_info, RESOLVE_TYPE_DEFAULT)) return false; if (kind != VARDECL_PARAM_REF || type_is_pointer(type_info->type)) break; RETURN_SEMA_ERROR(type_info, "A pointer type was expected for a ref argument, did you mean %s?", type_quoted_error_string(type_get_ptr(type_info->type))); + case VARDECL_PARAM: + case VARDECL_PARAM_EXPR: + case VARDECL_PARAM_CT: + case VARDECL_PARAM_CT_TYPE: + if (!type_info) break; + if (!sema_resolve_type_info(context, type_info, RESOLVE_TYPE_DEFAULT)) return false; + break; case VARDECL_CONST: case VARDECL_GLOBAL: case VARDECL_LOCAL: @@ -3797,7 +3802,7 @@ static bool sema_analyse_attributes_for_var(SemaContext *context, Decl *decl, bo domain = ATTR_GLOBAL; break; case VARDECL_PARAM: - case VARDECL_PARAM_REF: + case VARDECL_PARAM_REF: // DEPRECATED case VARDECL_PARAM_CT_TYPE: case VARDECL_PARAM_CT: domain = ATTR_PARAM; diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index c31ba76cc..b13593e10 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -10134,6 +10134,7 @@ bool sema_insert_method_call(SemaContext *context, Expr *method_call, Decl *meth // Deref / addr as needed. if (first_param->var.kind == VARDECL_PARAM_REF) { + // DEPRECATED ASSERT_SPAN(method_call, first->type_kind == TYPE_POINTER); first = first->pointer; } @@ -10150,6 +10151,7 @@ bool sema_insert_method_call(SemaContext *context, Expr *method_call, Decl *meth } else if (first_param->var.kind == VARDECL_PARAM_REF || !expr_may_ref(parent)) { + // DEPRECATED Expr *inner = expr_copy(parent); parent->expr_kind = EXPR_UNARY; Type *inner_type = inner->type; diff --git a/src/compiler/sema_liveness.c b/src/compiler/sema_liveness.c index 8b68c2cc8..e2c66b909 100644 --- a/src/compiler/sema_liveness.c +++ b/src/compiler/sema_liveness.c @@ -659,8 +659,8 @@ RETRY: case VARDECL_PARAM_EXPR: // These are never traced, they are folded in use. break; + case VARDECL_PARAM_REF: // DEPRECATED case VARDECL_PARAM_CT: - case VARDECL_PARAM_REF: case VARDECL_PARAM: sema_trace_type_liveness(decl->type); if (decl->var.init_expr && decl->var.init_expr->resolve_status == RESOLVE_DONE) diff --git a/test/test_suite/any/casting_voidptr_to_any.c3 b/test/test_suite/any/casting_voidptr_to_any.c3 index 154abb335..e4999e63a 100644 --- a/test/test_suite/any/casting_voidptr_to_any.c3 +++ b/test/test_suite/any/casting_voidptr_to_any.c3 @@ -20,7 +20,7 @@ fn void test(void* tptr){ iop = tptr; // #error: Casting a 'void*' to 'IOp' is not permitted iop.op(); } -fn void! main(String[] args) { +fn void main(String[] args) { Op()* t = mem::new(Op(), {.data = 1}); test(&t); } diff --git a/test/test_suite/arrays/array_bounds_check.c3t b/test/test_suite/arrays/array_bounds_check.c3t index 433fd9f66..77553df82 100644 --- a/test/test_suite/arrays/array_bounds_check.c3t +++ b/test/test_suite/arrays/array_bounds_check.c3t @@ -10,7 +10,7 @@ struct Foo int x; } -fn void! main() +fn void main() { for (usz i = 0; i < 20; i++) { @@ -24,6 +24,7 @@ loop.cond: ; preds = %checkok, %entry %0 = load i64, ptr %i, align 8 %gt = icmp ugt i64 20, %0 br i1 %gt, label %loop.body, label %loop.exit + loop.body: ; preds = %loop.cond %1 = load i64, ptr %i, align 8 %ge = icmp uge i64 %1, 2 @@ -40,7 +41,7 @@ checkok: ; preds = %loop.body br label %loop.cond loop.exit: ; preds = %loop.cond - ret i64 0 + ret void panic: ; preds = %loop.body store i64 2, ptr %taddr, align 8 diff --git a/test/test_suite/assert/assert_with_void.c3 b/test/test_suite/assert/assert_with_void.c3 index 671803880..1725e0bd2 100644 --- a/test/test_suite/assert/assert_with_void.c3 +++ b/test/test_suite/assert/assert_with_void.c3 @@ -1,7 +1,7 @@ module testing; import std::io; -fn void! main() +fn void main() { String[] s1; String[] s2; diff --git a/test/test_suite/assert/assertf.c3t b/test/test_suite/assert/assertf.c3t index bcbe59204..4920c5979 100644 --- a/test/test_suite/assert/assertf.c3t +++ b/test/test_suite/assert/assertf.c3t @@ -2,7 +2,7 @@ // #safe: yes module main; -fn void! main() +fn void main() { for (usz i = 0; i < 100000000; i++) { @@ -12,8 +12,6 @@ fn void! main() /* #expect: main.ll -define i64 @main.main() #0 { -entry: %i = alloca i64, align 8 %taddr = alloca i64, align 8 %varargslots = alloca [2 x %any], align 16 @@ -50,6 +48,4 @@ assert_ok: ; preds = %loop.body store i64 %add, ptr %i, align 8 br label %loop.cond loop.exit: ; preds = %loop.cond - ret i64 0 -} diff --git a/test/test_suite/bitstruct/bitstruct_in_subarray.c3t b/test/test_suite/bitstruct/bitstruct_in_subarray.c3t index bb264a6a2..0e5396d88 100644 --- a/test/test_suite/bitstruct/bitstruct_in_subarray.c3t +++ b/test/test_suite/bitstruct/bitstruct_in_subarray.c3t @@ -6,14 +6,15 @@ bitstruct StructFieldKind : char bool is_union : 1; } -fn void! main() +fn void main() { StructFieldKind[] xx = { { .is_union = true } }; } /* #expect: test.ll -define i64 @test.main() #0 { + +define void @test.main() #0 { entry: %xx = alloca %"char[]", align 8 %literal = alloca [1 x i8], align 1 @@ -21,5 +22,5 @@ entry: %0 = insertvalue %"char[]" undef, ptr %literal, 0 %1 = insertvalue %"char[]" %0, i64 1, 1 store %"char[]" %1, ptr %xx, align 8 - ret i64 0 + ret void } \ No newline at end of file diff --git a/test/test_suite/cast/cast_bitstruct_etc.c3t b/test/test_suite/cast/cast_bitstruct_etc.c3t index e34922498..daee17bd4 100644 --- a/test/test_suite/cast/cast_bitstruct_etc.c3t +++ b/test/test_suite/cast/cast_bitstruct_etc.c3t @@ -1,7 +1,7 @@ // #target: macos-x64 module test; -fn void! main() +fn void main() { Enum e = ENUM1; ushort x = (ushort)Foo{ .x = e }; @@ -32,5 +32,3 @@ bitstruct Foo : ushort %zext1 = zext i8 %2 to i16 %3 = and i16 %zext1, 255 store i16 %3, ptr %z, align 2 - ret i64 0 -} \ No newline at end of file diff --git a/test/test_suite/cast/cast_narrow_alias.c3t b/test/test_suite/cast/cast_narrow_alias.c3t index c8c06de5e..c20d40af7 100644 --- a/test/test_suite/cast/cast_narrow_alias.c3t +++ b/test/test_suite/cast/cast_narrow_alias.c3t @@ -1,7 +1,7 @@ // #target: macos-x64 module abc; def UInt8 = char; -fn void! main() +fn void main() { UInt8 x = 17; UInt8 y = 5; @@ -9,7 +9,6 @@ fn void! main() } /* #expect: abc.ll -define i64 @abc.main() #0 { entry: %x = alloca i8, align 1 %y = alloca i8, align 1 @@ -25,5 +24,3 @@ entry: %and = and i32 %2, 1 %trunc = trunc i32 %and to i8 store i8 %trunc, ptr %z, align 1 - ret i64 0 -} diff --git a/test/test_suite/compile_time/ct_assert_bug.c3 b/test/test_suite/compile_time/ct_assert_bug.c3 index a5a6370c0..5b6582bbc 100644 --- a/test/test_suite/compile_time/ct_assert_bug.c3 +++ b/test/test_suite/compile_time/ct_assert_bug.c3 @@ -2,7 +2,7 @@ module testing; import std::io; -fn void! main() +fn void main() { String[] s1; String[] s2; diff --git a/test/test_suite/compile_time_introspection/defined_2.c3t b/test/test_suite/compile_time_introspection/defined_2.c3t index 743cba38f..fec0f75d8 100644 --- a/test/test_suite/compile_time_introspection/defined_2.c3t +++ b/test/test_suite/compile_time_introspection/defined_2.c3t @@ -3,7 +3,7 @@ module testing; import std::io; -fn void! main() +fn void main() { Bits b1; Bits b2; @@ -22,7 +22,6 @@ fn bool Bits.equals(a, Bits b) /* #expect: testing.ll -define i64 @testing.main() #0 { entry: %b1 = alloca i8, align 1 %b2 = alloca i8, align 1 @@ -39,5 +38,3 @@ entry: %3 = load i8, ptr %b, align 1 %4 = call i8 @testing.Bits.equals(i8 zeroext %2, i8 zeroext %3) store i8 %4, ptr %x, align 1 - ret i64 0 -} \ No newline at end of file diff --git a/test/test_suite/constants/constant_struct.c3 b/test/test_suite/constants/constant_struct.c3 index 109b79ae9..2bb0f1190 100644 --- a/test/test_suite/constants/constant_struct.c3 +++ b/test/test_suite/constants/constant_struct.c3 @@ -12,7 +12,7 @@ struct Bcd const Abc FOO = { 2 }; -fn void! main() +fn void main() { Bcd a = { FOO }; } diff --git a/test/test_suite/contracts/macro_ensure_static.c3 b/test/test_suite/contracts/macro_ensure_static.c3 index bd4368086..883f5bb36 100644 --- a/test/test_suite/contracts/macro_ensure_static.c3 +++ b/test/test_suite/contracts/macro_ensure_static.c3 @@ -8,7 +8,7 @@ macro check(int a) if (a < 0) return -1; // #error: @ensure return 100; } -fn void! main() +fn void main() { check(43); } \ No newline at end of file diff --git a/test/test_suite/defer/defer_catch_mix.c3t b/test/test_suite/defer/defer_catch_mix.c3t index ba7fe7395..20402f275 100644 --- a/test/test_suite/defer/defer_catch_mix.c3t +++ b/test/test_suite/defer/defer_catch_mix.c3t @@ -12,7 +12,7 @@ fn char[]! fileReader(String filename, char[] buffer) return buffer; } -fn void! main() +fn void main() { char[] !buffer = mem::new_array(char, 12); buffer = fileReader("not_found.txt", buffer); @@ -232,7 +232,7 @@ voiderr76: ; preds = %noerr_block74, %gua ret i64 0 } ; Function Attrs: nounwind uwtable(sync) -define i64 @test.main() #0 { +define void @test.main() #0 { entry: %buffer = alloca %"char[]", align 8 %buffer.f = alloca i64, align 8 @@ -254,7 +254,6 @@ entry: %taddr10 = alloca %"any[]", align 8 %retparam14 = alloca %"char[]", align 8 %taddr15 = alloca %"char[]", align 8 - %reterr = alloca i64, align 8 store ptr null, ptr %.cachedtype, align 8 call void @llvm.memcpy.p0.p0.i32(ptr align 8 %allocator, ptr align 8 @std.core.mem.allocator.thread_allocator, i32 16, i1 false) call void @llvm.memcpy.p0.p0.i32(ptr align 8 %allocator1, ptr align 8 %allocator, i32 16, i1 false) @@ -349,36 +348,11 @@ after_check18: ; preds = %after_check13 store i64 0, ptr %buffer.f, align 8 br label %after_assign after_assign: ; preds = %after_check18, %assign_optional17, %assign_optional12 - ret i64 0 + ret void } -; Function Attrs: nounwind uwtable(sync) + define i32 @main(i32 %0, ptr %1) #0 { entry: - %blockret = alloca i32, align 4 - %temp_err = alloca i64, align 8 - br label %testblock -testblock: ; preds = %entry - %2 = call i64 @test.main() - %not_err = icmp eq i64 %2, 0 - %3 = call i1 @llvm.expect.i1(i1 %not_err, i1 true) - br i1 %3, label %after_check, label %assign_optional -assign_optional: ; preds = %testblock - store i64 %2, ptr %temp_err, align 8 - br label %end_block -after_check: ; preds = %testblock - store i64 0, ptr %temp_err, align 8 - br label %end_block -end_block: ; preds = %after_check, %assign_optional - %4 = load i64, ptr %temp_err, align 8 - %i2b = icmp ne i64 %4, 0 - br i1 %i2b, label %if.then, label %if.exit -if.then: ; preds = %end_block - store i32 1, ptr %blockret, align 4 - br label %expr_block.exit -if.exit: ; preds = %end_block - store i32 0, ptr %blockret, align 4 - br label %expr_block.exit -expr_block.exit: ; preds = %if.exit, %if.then - %5 = load i32, ptr %blockret, align 4 - ret i32 %5 + call void @test.main() + ret i32 0 } diff --git a/test/test_suite/dynamic/duplicate_definition.c3 b/test/test_suite/dynamic/duplicate_definition.c3 index 139d90658..5d0e5583e 100644 --- a/test/test_suite/dynamic/duplicate_definition.c3 +++ b/test/test_suite/dynamic/duplicate_definition.c3 @@ -5,7 +5,7 @@ interface Abc fn void abc(); fn void abc(); // #error: Duplicate definition } -fn void! main() +fn void main() { Abc* g; g.abc(); diff --git a/test/test_suite/enumerations/introspection_data_error.c3t b/test/test_suite/enumerations/introspection_data_error.c3t index d20614c2d..6d642f7f2 100644 --- a/test/test_suite/enumerations/introspection_data_error.c3t +++ b/test/test_suite/enumerations/introspection_data_error.c3t @@ -6,7 +6,7 @@ enum Boom: int (String a) { module app; import std::io, boom; -fn void! main(String[] args) { +fn void main(String[] args) { io::printn(Boom.BOOM); } /* #expect: boom.ll diff --git a/test/test_suite/errors/optional_designated.c3 b/test/test_suite/errors/optional_designated.c3 index 866bed82b..ccc65c05a 100644 --- a/test/test_suite/errors/optional_designated.c3 +++ b/test/test_suite/errors/optional_designated.c3 @@ -2,7 +2,7 @@ module foo; struct Foo { int a; } struct Bar { int b; Foo f; } -fn void! main() +fn void main() { Bar { .f = Foo { foo() } }; // #error: not be discarded } diff --git a/test/test_suite/expressions/incdec_overload.c3t b/test/test_suite/expressions/incdec_overload.c3t index a9a6fa585..fefc8c27b 100644 --- a/test/test_suite/expressions/incdec_overload.c3t +++ b/test/test_suite/expressions/incdec_overload.c3t @@ -4,20 +4,19 @@ import std; def Abc = HashMap(); Abc m; -fn void! main() +fn void main() { m[3] = 100; int! x = m[3]--; - assert(m[3]! == 99); - assert(x! == 100); + assert(m[3]!! == 99); + assert(x!! == 100); x = ++m[3]; - assert(m[3]! == 100); - assert(x! == 100); + assert(m[3]!! == 100); + assert(x!! == 100); } /* #expect: test.ll -define i64 @test.main() #0 { entry: %x = alloca i32, align 4 %x.f = alloca i64, align 8 @@ -176,44 +175,5 @@ after_check43: ; preds = %after_check39 br label %after_assign44 after_assign44: ; preds = %after_check43, %assign_optional42, %assign_optional38, %optional_assign_jump33, %optional_assign_jump24 - ret i64 0 + ret void } - -; Function Attrs: nounwind uwtable -define i32 @main(i32 %0, ptr %1) #0 { -entry: - %blockret = alloca i32, align 4 - %temp_err = alloca i64, align 8 - br label %testblock - -testblock: ; preds = %entry - %2 = call i64 @test.main() - %not_err = icmp eq i64 %2, 0 - %3 = call i1 @llvm.expect.i1(i1 %not_err, i1 true) - br i1 %3, label %after_check, label %assign_optional - -assign_optional: ; preds = %testblock - store i64 %2, ptr %temp_err, align 8 - br label %end_block - -after_check: ; preds = %testblock - store i64 0, ptr %temp_err, align 8 - br label %end_block - -end_block: ; preds = %after_check, %assign_optional - %4 = load i64, ptr %temp_err, align 8 - %i2b = icmp ne i64 %4, 0 - br i1 %i2b, label %if.then, label %if.exit - -if.then: ; preds = %end_block - store i32 1, ptr %blockret, align 4 - br label %expr_block.exit - -if.exit: ; preds = %end_block - store i32 0, ptr %blockret, align 4 - br label %expr_block.exit - -expr_block.exit: ; preds = %if.exit, %if.then - %5 = load i32, ptr %blockret, align 4 - ret i32 %5 -} \ No newline at end of file diff --git a/test/test_suite/expressions/optional_and_error.c3 b/test/test_suite/expressions/optional_and_error.c3 index e9861d494..aa9ce69ed 100644 --- a/test/test_suite/expressions/optional_and_error.c3 +++ b/test/test_suite/expressions/optional_and_error.c3 @@ -1,7 +1,7 @@ module testing; import std::io; -fn void! main() +fn void main() { bool ok; if (ok && !foo()) io::printfn("nok"); // #error: The expression may not be an optional diff --git a/test/test_suite/functions/function_alias_llvm_check.c3t b/test/test_suite/functions/function_alias_llvm_check.c3t index 7214c2e14..bc95ffdb8 100644 --- a/test/test_suite/functions/function_alias_llvm_check.c3t +++ b/test/test_suite/functions/function_alias_llvm_check.c3t @@ -24,7 +24,7 @@ fn void Foo.add_fn_b(&self, FnB f) => self.bFuncs.push(f); fn void a_func(Foo* foo) {} fn void b_func(Foo* foo) {} -fn void! main() +fn void main() { Foo foo; defer foo.deinit()!!; @@ -34,7 +34,8 @@ fn void! main() /* #expect: repro.ll -define i64 @repro.main() #0 { + +define void @repro.main() #0 { entry: %foo = alloca %Foo, align 8 %error_var = alloca i64, align 8 diff --git a/test/test_suite/functions/recursive_through_generic.c3 b/test/test_suite/functions/recursive_through_generic.c3 index 919fac100..ebdb41ff8 100644 --- a/test/test_suite/functions/recursive_through_generic.c3 +++ b/test/test_suite/functions/recursive_through_generic.c3 @@ -1,7 +1,7 @@ module oups; import std::collections::map; -fn void! main() +fn void main() { } diff --git a/test/test_suite/generic/generic_builtin.c3t b/test/test_suite/generic/generic_builtin.c3t index baaa28f29..5643b3c2d 100644 --- a/test/test_suite/generic/generic_builtin.c3t +++ b/test/test_suite/generic/generic_builtin.c3t @@ -9,7 +9,7 @@ fn int iadd(int a, int b) @builtin => module main; import std::io, add, iadd; -fn void! main() +fn void main() { io::printfn("%s", iadd(1,2)); // Fine io::printfn("%s", add()(1,2)); // Error diff --git a/test/test_suite/generic/generic_lambda_complex.c3t b/test/test_suite/generic/generic_lambda_complex.c3t index cb9239391..90b686df6 100644 --- a/test/test_suite/generic/generic_lambda_complex.c3t +++ b/test/test_suite/generic/generic_lambda_complex.c3t @@ -154,12 +154,12 @@ struct Bar String bar; } -fn void! main() +fn void main() { String foo_tmpl = "<<{{foo}} | {{bar}}>>"; FooTmpl ft; - ft.init(foo_tmpl, using: allocator::temp())!; + ft.init(foo_tmpl, using: allocator::temp())!!; defer ft.free()!!; @@ -167,18 +167,18 @@ fn void! main() /* #expect: text_test.ll - - -define i64 @text_test.main() #0 { +define void @text_test.main() #0 { entry: %foo_tmpl = alloca %"char[]", align 8 %ft = alloca %TextTemplate, align 8 %error_var = alloca i64, align 8 %indirectarg = alloca %"char[]", align 8 %indirectarg1 = alloca %any, align 8 - %error_var2 = alloca i64, align 8 %varargslots = alloca [1 x %any], align 16 - %indirectarg6 = alloca %"any[]", align 8 + %indirectarg2 = alloca %"any[]", align 8 + %error_var3 = alloca i64, align 8 + %varargslots8 = alloca [1 x %any], align 16 + %indirectarg10 = alloca %"any[]", align 8 store %"char[]" { ptr @.str, i64 21 }, ptr %foo_tmpl, align 8 call void @llvm.memset.p0.i64(ptr align 8 %ft, i8 0, i64 72, i1 false) %0 = load ptr, ptr @std.core.mem.allocator.thread_temp_allocator, align 8 @@ -205,38 +205,44 @@ if.exit: ; preds = %if.then, %entry assign_optional: ; preds = %if.exit store i64 %4, ptr %error_var, align 8 - br label %guard_block + br label %panic_block after_check: ; preds = %if.exit br label %noerr_block -guard_block: ; preds = %assign_optional - %6 = load i64, ptr %error_var, align 8 - ret i64 %6 - -noerr_block: ; preds = %after_check - %7 = call i64 @"abc$text_test.Foo$.TextTemplate.free"(ptr %ft) - %not_err3 = icmp eq i64 %7, 0 - %8 = call i1 @llvm.expect.i1(i1 %not_err3, i1 true) - br i1 %8, label %after_check5, label %assign_optional4 - -assign_optional4: ; preds = %noerr_block - store i64 %7, ptr %error_var2, align 8 - br label %panic_block - -after_check5: ; preds = %noerr_block - br label %noerr_block7 - -panic_block: ; preds = %assign_optional4 - %9 = insertvalue %any undef, ptr %error_var2, 0 - %10 = insertvalue %any %9, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1 - store %any %10, ptr %varargslots, align 16 - %11 = insertvalue %"any[]" undef, ptr %varargslots, 0 - %"$$temp" = insertvalue %"any[]" %11, i64 1, 1 - store %"any[]" %"$$temp", ptr %indirectarg6, align 8 - call void @std.core.builtin.panicf(ptr @.panic_msg, i64 36, ptr @.file, i64 25 +panic_block: ; preds = %assign_optional + %6 = insertvalue %any undef, ptr %error_var, 0 + %7 = insertvalue %any %6, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1 + store %any %7, ptr %varargslots, align 16 + %8 = insertvalue %"any[]" undef, ptr %varargslots, 0 + %"$$temp" = insertvalue %"any[]" %8, i64 1, 1 + store %"any[]" %"$$temp", ptr %indirectarg2, align 8 + call void @std.core.builtin.panicf(ptr @.panic_msg, i64 36, ptr @.file, i64 25, ptr @.func, i64 4, i32 161, ptr byval(%"any[]") align 8 %indirectarg2) unreachable -noerr_block7: ; preds = %after_check5 - ret i64 0 +noerr_block: ; preds = %after_check + %9 = call i64 @"abc$text_test.Foo$.TextTemplate.free"(ptr %ft) + %not_err4 = icmp eq i64 %9, 0 + %10 = call i1 @llvm.expect.i1(i1 %not_err4, i1 true) + br i1 %10, label %after_check6, label %assign_optional5 + +assign_optional5: ; preds = %noerr_block + store i64 %9, ptr %error_var3, align 8 + br label %panic_block7 + +after_check6: ; preds = %noerr_block + br label %noerr_block11 + +panic_block7: ; preds = %assign_optional5 + %11 = insertvalue %any undef, ptr %error_var3, 0 + %12 = insertvalue %any %11, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1 + store %any %12, ptr %varargslots8, align 16 + %13 = insertvalue %"any[]" undef, ptr %varargslots8, 0 + %"$$temp9" = insertvalue %"any[]" %13, i64 1, 1 + store %"any[]" %"$$temp9", ptr %indirectarg10, align 8 + call void @std.core.builtin.panicf(ptr @.panic_msg, i64 36, ptr @.file, i64 25, ptr @.func, i64 4, i32 162, ptr byval(%"any[]") align 8 %indirectarg10) + unreachable + +noerr_block11: ; preds = %after_check6 + ret void } diff --git a/test/test_suite/import/import_twice.c3 b/test/test_suite/import/import_twice.c3 index da7fed2ec..815d41040 100644 --- a/test/test_suite/import/import_twice.c3 +++ b/test/test_suite/import/import_twice.c3 @@ -2,7 +2,7 @@ module foo; import std::io; import std::io; // #error: imported more than -fn void! main() +fn void main() { io::printn("Hello world"); } diff --git a/test/test_suite/macros/implicit_return_opt.c3 b/test/test_suite/macros/implicit_return_opt.c3 index d92ffb5d6..91c5cb20e 100644 --- a/test/test_suite/macros/implicit_return_opt.c3 +++ b/test/test_suite/macros/implicit_return_opt.c3 @@ -1,9 +1,9 @@ module test; import std::io; -fn void! main() +fn void main() { - int x = run()!; // #error: You cannot cast + int x = run()!!; // #error: You cannot cast io::printfn("x=%d", x); } diff --git a/test/test_suite/macros/macro_body_defer.c3t b/test/test_suite/macros/macro_body_defer.c3t index e20d0e336..a3fae041b 100644 --- a/test/test_suite/macros/macro_body_defer.c3t +++ b/test/test_suite/macros/macro_body_defer.c3t @@ -17,7 +17,7 @@ macro foo_defer() printf("B\n"); defer printf("C\n"); } -fn void! main() +fn void main() { foo_defer(); @foo_test(34) { @@ -54,10 +54,8 @@ entry: store i32 1, ptr %0, align 4 ret i64 0 } - -define i64 @foo.main() #0 { +define void @foo.main() #0 { entry: - %reterr = alloca i64, align 8 call void (ptr, ...) @printf(ptr @.str) call void (ptr, ...) @printf(ptr @.str.1) call void (ptr, ...) @printf(ptr @.str.2) @@ -65,61 +63,25 @@ entry: call void (ptr, ...) @printf(ptr @.str.4, i32 34) call void (ptr, ...) @printf(ptr @.str.5, i32 34) br label %loop.body - loop.body: ; preds = %entry call void (ptr, ...) @printf(ptr @.str.6) call void (ptr, ...) @printf(ptr @.str.7) call void (ptr, ...) @printf(ptr @.str.8, i32 3) call void (ptr, ...) @printf(ptr @.str.9) br label %loop.exit - loop.exit: ; preds = %loop.body br label %loop.body1 - loop.body1: ; preds = %loop.exit call void (ptr, ...) @printf(ptr @.str.10) call void (ptr, ...) @printf(ptr @.str.11) call void (ptr, ...) @printf(ptr @.str.12) call void (ptr, ...) @printf(ptr @.str.13, i32 3) call void (ptr, ...) @printf(ptr @.str.14) - ret i64 0 + ret void } - define i32 @main(i32 %0, ptr %1) #0 { entry: - %blockret = alloca i32, align 4 - %temp_err = alloca i64, align 8 - br label %testblock - -testblock: ; preds = %entry - %2 = call i64 @foo.main() - %not_err = icmp eq i64 %2, 0 - %3 = call i1 @llvm.expect.i1(i1 %not_err, i1 true) - br i1 %3, label %after_check, label %assign_optional - -assign_optional: ; preds = %testblock - store i64 %2, ptr %temp_err, align 8 - br label %end_block - -after_check: ; preds = %testblock - store i64 0, ptr %temp_err, align 8 - br label %end_block - -end_block: ; preds = %after_check, %assign_optional - %4 = load i64, ptr %temp_err, align 8 - %i2b = icmp ne i64 %4, 0 - br i1 %i2b, label %if.then, label %if.exit - -if.then: ; preds = %end_block - store i32 1, ptr %blockret, align 4 - br label %expr_block.exit - -if.exit: ; preds = %end_block - store i32 0, ptr %blockret, align 4 - br label %expr_block.exit - -expr_block.exit: ; preds = %if.exit, %if.then - %5 = load i32, ptr %blockret, align 4 - ret i32 %5 + call void @foo.main() + ret i32 0 } diff --git a/test/test_suite/macros/unifying_implicit_void.c3t b/test/test_suite/macros/unifying_implicit_void.c3t index 319c69343..4c815c827 100644 --- a/test/test_suite/macros/unifying_implicit_void.c3t +++ b/test/test_suite/macros/unifying_implicit_void.c3t @@ -2,11 +2,11 @@ module oups; import std::io; -fn void! main() +fn void main() { ByteReader r; InStream s = &r; - s.foo()!; + s.foo()!!; } macro InStream.foo(&self) @@ -22,8 +22,7 @@ macro InStream.foo(&self) /* #expect: oups.ll - -define i64 @oups.main() #0 { +define void @oups.main() #0 { entry: %r = alloca %ByteReader, align 8 %s = alloca %any, align 8 @@ -34,6 +33,8 @@ entry: %.cachedtype = alloca ptr, align 8 %retparam = alloca i8, align 1 %err = alloca i64, align 8 + %varargslots = alloca [1 x %any], align 16 + %indirectarg = alloca %"any[]", align 8 store ptr null, ptr %.cachedtype, align 8 call void @llvm.memset.p0.i64(ptr align 8 %r, i8 0, i64 24, i1 false) %0 = insertvalue %any undef, ptr %r, 0 @@ -97,12 +98,18 @@ end_block: ; preds = %after_check4, %assi if.then: ; preds = %end_block %16 = load i64, ptr %err, align 8 store i64 %16, ptr %error_var, align 8 - br label %guard_block + br label %panic_block if.exit: ; preds = %end_block br label %noerr_block -guard_block: ; preds = %if.then - %17 = load i64, ptr %error_var, align 8 - ret i64 %17 +panic_block: ; preds = %if.then + %17 = insertvalue %any undef, ptr %error_var, 0 + %18 = insertvalue %any %17, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1 + store %any %18, ptr %varargslots, align 16 + %19 = insertvalue %"any[]" undef, ptr %varargslots, 0 + %"$$temp" = insertvalue %"any[]" %19, i64 1, 1 + store %"any[]" %"$$temp", ptr %indirectarg, align 8 + call void @std.core.builtin.panicf(ptr @.panic_msg.1, i64 36, ptr @.file, i64 25, ptr @.func, i64 4, i32 8, ptr byval(%"any[]") align 8 %indirectarg) + unreachable noerr_block: ; preds = %if.exit - ret i64 0 + ret void } \ No newline at end of file diff --git a/test/test_suite/slices/slice_inline.c3t b/test/test_suite/slices/slice_inline.c3t index 5e395737f..8a4ca0027 100644 --- a/test/test_suite/slices/slice_inline.c3t +++ b/test/test_suite/slices/slice_inline.c3t @@ -10,7 +10,7 @@ fn void Data.not_working(self) { fn void Data.working(self) { self.data[:self.data.len]; } -fn void! main(String[] args) { +fn void main(String[] args) { Data d; d.not_working(); d.working(); diff --git a/test/test_suite/statements/nextcase_const.c3t b/test/test_suite/statements/nextcase_const.c3t index 571f7befe..1a444efb3 100644 --- a/test/test_suite/statements/nextcase_const.c3t +++ b/test/test_suite/statements/nextcase_const.c3t @@ -1,7 +1,7 @@ // #target: macos-x64 module test; -fn void! main() +fn void main() { int a; switch (a) @@ -17,7 +17,6 @@ fn void! main() /* #expect: test.ll -define i64 @test.main() #0 { entry: %a = alloca i32, align 4 %switch = alloca i32, align 4 @@ -51,5 +50,3 @@ switch.default: ; preds = %next_if4 store i32 %sub, ptr %a, align 4 br label %switch.exit switch.exit: ; preds = %switch.default - ret i64 0 -} \ No newline at end of file diff --git a/test/test_suite/statements/nextcase_missing_case.c3 b/test/test_suite/statements/nextcase_missing_case.c3 index 01f3e90ee..1b2871b5b 100644 --- a/test/test_suite/statements/nextcase_missing_case.c3 +++ b/test/test_suite/statements/nextcase_missing_case.c3 @@ -1,7 +1,7 @@ module test; import std::io; -fn void! main() +fn void main() { int a; switch (a)