| ... | ... | @@ -121,6 +121,9 @@ extern fn main(c_argc: i32, c_argv: [*][*]u8, c_envp: [*]?[*]u8) i32 { |
| 121 | 121 | // This is marked inline because for some reason LLVM in release mode fails to inline it, |
| 122 | 122 | // and we want fewer call frames in stack traces. |
| 123 | 123 | inline fn callMain() u8 { |
| 124 | // General error message for a malformed return type |
| 125 | const compile_err_prefix = "expected return type of main to be 'u8', 'noreturn', 'void', '!void', or '!u8', found '"; |
| 126 | const compile_err = compile_err_prefix ++ @typeName(@typeOf(root.main).ReturnType) ++ "'"; |
| 124 | 127 | switch (@typeId(@typeOf(root.main).ReturnType)) { |
| 125 | 128 | .NoReturn => { |
| 126 | 129 | root.main(); |
| ... | ... | @@ -131,23 +134,30 @@ inline fn callMain() u8 { |
| 131 | 134 | }, |
| 132 | 135 | .Int => { |
| 133 | 136 | if (@typeOf(root.main).ReturnType.bit_count != 8) { |
| 134 | | @compileError("expected return type of main to be 'u8', 'noreturn', 'void', or '!void'"); |
| 137 | @compileError(compile_err); |
| 135 | 138 | } |
| 136 | 139 | return root.main(); |
| 137 | 140 | }, |
| 138 | | .ErrorUnion => { |
| 139 | | root.main() catch |err| { |
| 140 | | std.debug.warn("error: {}\n", @errorName(err)); |
| 141 | | if (builtin.os != builtin.Os.zen) { |
| 142 | | if (@errorReturnTrace()) |trace| { |
| 143 | | std.debug.dumpStackTrace(trace.*); |
| 141 | builtin.TypeId.ErrorUnion => { |
| 142 | const PayloadType = @typeOf(root.main).ReturnType.Payload; |
| 143 | // In this case the error should include the payload type |
| 144 | const payload_err = compile_err_prefix ++ "!" ++ @typeName(PayloadType) ++ "'"; |
| 145 | // If the payload is void or a u8 |
| 146 | if (@typeId(PayloadType) == builtin.TypeId.Void or (@typeId(PayloadType) == builtin.TypeId.Int and PayloadType.bit_count == 8)) { |
| 147 | const tmp = root.main() catch |err| { |
| 148 | std.debug.warn("error: {}\n", @errorName(err)); |
| 149 | if (builtin.os != builtin.Os.zen) { |
| 150 | if (@errorReturnTrace()) |trace| { |
| 151 | std.debug.dumpStackTrace(trace.*); |
| 152 | } |
| 144 | 153 | } |
| 145 | | } |
| 146 | | return 1; |
| 147 | | }; |
| 148 | | return 0; |
| 154 | return 1; |
| 155 | }; |
| 156 | // If main didn't error, return 0 or the exit code |
| 157 | return if (PayloadType == void) 0 else tmp; |
| 158 | } else @compileError(payload_err); |
| 149 | 159 | }, |
| 150 | | else => @compileError("expected return type of main to be 'u8', 'noreturn', 'void', or '!void'"), |
| 160 | else => @compileError(compile_err), |
| 151 | 161 | } |
| 152 | 162 | } |
| 153 | 163 | |