commit 9a9a7daef0aff340e029fb9bb6d29361a3d7e767 (tree)
parent 0435026474cc3489337f3d6a7ac9d2e5cb1b7044
Author: Andrew Kelley <andrew@ziglang.org>
Date: Tue, 16 Jul 2019 11:50:17 -0400
Merge branch 'SamTebbs33-main-return'
Diffstat:
5 files changed, 40 insertions(+), 13 deletions(-)
diff --git a/std/special/start.zig b/std/special/start.zig
@@ -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),
}
}
diff --git a/test/build_examples.zig b/test/build_examples.zig
@@ -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");
diff --git a/test/compile_errors.zig b/test/compile_errors.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(
diff --git a/test/standalone/main_return_error/error_u8.zig b/test/standalone/main_return_error/error_u8.zig
@@ -0,0 +1,7 @@
+const Err = error {
+ Foo
+};
+
+pub fn main() !u8 {
+ return Err.Foo;
+}
diff --git a/test/standalone/main_return_error/error_u8_non_zero.zig b/test/standalone/main_return_error/error_u8_non_zero.zig
@@ -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;
+}