Merge branch 'SamTebbs33-main-return'
commit
9a9a7daef0
|
@ -125,10 +125,13 @@ extern fn main(c_argc: i32, c_argv: [*][*]u8, c_envp: [*]?[*]u8) i32 {
|
|||
return callMainWithArgs(@intCast(usize, c_argc), c_argv, envp);
|
||||
}
|
||||
|
||||
// General error message for a malformed return type
|
||||
const bad_main_ret = "expected return type of main to be 'void', '!void', 'noreturn', 'u8', or '!u8'";
|
||||
|
||||
// This is marked inline because for some reason LLVM in release mode fails to inline it,
|
||||
// and we want fewer call frames in stack traces.
|
||||
inline fn callMain() u8 {
|
||||
switch (@typeId(@typeOf(root.main).ReturnType)) {
|
||||
switch (@typeInfo(@typeOf(root.main).ReturnType)) {
|
||||
.NoReturn => {
|
||||
root.main();
|
||||
},
|
||||
|
@ -136,25 +139,32 @@ inline fn callMain() u8 {
|
|||
root.main();
|
||||
return 0;
|
||||
},
|
||||
.Int => {
|
||||
if (@typeOf(root.main).ReturnType.bit_count != 8) {
|
||||
@compileError("expected return type of main to be 'u8', 'noreturn', 'void', or '!void'");
|
||||
.Int => |info| {
|
||||
if (info.bits != 8) {
|
||||
@compileError(bad_main_ret);
|
||||
}
|
||||
return root.main();
|
||||
},
|
||||
.ErrorUnion => {
|
||||
root.main() catch |err| {
|
||||
const result = root.main() catch |err| {
|
||||
std.debug.warn("error: {}\n", @errorName(err));
|
||||
if (builtin.os != builtin.Os.zen) {
|
||||
if (@errorReturnTrace()) |trace| {
|
||||
std.debug.dumpStackTrace(trace.*);
|
||||
}
|
||||
if (@errorReturnTrace()) |trace| {
|
||||
std.debug.dumpStackTrace(trace.*);
|
||||
}
|
||||
return 1;
|
||||
};
|
||||
return 0;
|
||||
switch (@typeInfo(@typeOf(result))) {
|
||||
.Void => return 0,
|
||||
.Int => |info| {
|
||||
if (info.bits != 8) {
|
||||
@compileError(bad_main_ret);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
else => @compileError(bad_main_ret),
|
||||
}
|
||||
},
|
||||
else => @compileError("expected return type of main to be 'u8', 'noreturn', 'void', or '!void'"),
|
||||
else => @compileError(bad_main_ret),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@ pub fn addCases(cases: *tests.BuildExamplesContext) void {
|
|||
cases.addC("example/hello_world/hello_libc.zig");
|
||||
cases.add("example/cat/main.zig");
|
||||
cases.add("example/guess_number/main.zig");
|
||||
cases.add("test/standalone/main_return_error/error_u8.zig");
|
||||
cases.add("test/standalone/main_return_error/error_u8_non_zero.zig");
|
||||
cases.addBuildFile("test/standalone/main_pkg_path/build.zig");
|
||||
cases.addBuildFile("example/shared_library/build.zig");
|
||||
cases.addBuildFile("example/mix_o_files/build.zig");
|
||||
|
|
|
@ -2247,7 +2247,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
|||
"wrong return type for main",
|
||||
\\pub fn main() f32 { }
|
||||
,
|
||||
"error: expected return type of main to be 'u8', 'noreturn', 'void', or '!void'",
|
||||
"error: expected return type of main to be 'void', '!void', 'noreturn', 'u8', or '!u8'",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
|
@ -2255,7 +2255,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
|||
\\pub fn main() ??void {
|
||||
\\}
|
||||
,
|
||||
"error: expected return type of main to be 'u8', 'noreturn', 'void', or '!void'",
|
||||
"error: expected return type of main to be 'void', '!void', 'noreturn', 'u8', or '!u8'",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
const Err = error {
|
||||
Foo
|
||||
};
|
||||
|
||||
pub fn main() !u8 {
|
||||
return Err.Foo;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
const Err = error { Foo };
|
||||
|
||||
fn foo() u8 { var x = @intCast(u8, 9); return x; }
|
||||
|
||||
pub fn main() !u8 {
|
||||
if (foo() == 7) return Err.Foo;
|
||||
return 123;
|
||||
}
|
Loading…
Reference in New Issue