diff --git a/doc/langref.md b/doc/langref.md index 68c74bcbf3..d2068dfd88 100644 --- a/doc/langref.md +++ b/doc/langref.md @@ -155,7 +155,7 @@ GotoExpression = "goto" Symbol GroupedExpression = "(" Expression ")" -KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "error" | "type" | "this" +KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "error" | "type" | "this" | "unreachable" ContainerDecl = option("extern" | "packed") ("struct" | "enum" | "union") "{" many(ContainerMember) "}" @@ -213,60 +213,6 @@ f32 float 32-bit floating point f64 double 64-bit floating point ``` -### Boolean Type - -The boolean type has the name `bool` and represents either true or false. - -### Function Type - -TODO - -### Fixed-Size Array Type - -Example: The string `"aoeu"` has type `[4]u8`. - -The size is known at compile time and is part of the type. - -### Slice Type - -A slice can be obtained with the slicing syntax: `array[start...end]` - -Example: `"aoeu"[0...2]` has type `[]u8`. - -### Struct Type - -TODO - -### Enum Type - -TODO - -### Maybe Type - -TODO - -### Pure Error Type - -TODO - -### Error Union Type - -TODO - -### Pointer Type - -TODO - -### Unreachable Type - -The unreachable type has the name `unreachable`. TODO explanation - -### Void Type - -The void type has the name `void`. void types are zero bits and are omitted -from codegen. - - ## Expressions ### Literals @@ -347,31 +293,6 @@ has a terminating null byte. Floating point | 123.0E+77 | Optional Hex floating point | 0x103.70p-5 | Optional -### Identifiers - -TODO - -### Declarations - -Declarations have type `void`. - -#### Function Declarations - -TODO - -#### Variable Declarations - -TODO - -#### Struct Declarations - -TODO - -#### Enum Declarations - -TODO - - ## Built-in Functions Built-in functions are prefixed with `@`. Remember that the `comptime` keyword on @@ -682,10 +603,6 @@ code. This function returns an integer type with the given signness and bit count. -### @setFnTest(func) - -Makes the target function a test function. - ### @setDebugSafety(scope, safety_on: bool) Sets a whether we want debug safety checks on for a given scope. diff --git a/doc/vim/syntax/zig.vim b/doc/vim/syntax/zig.vim index a3e39415ec..643f326ad2 100644 --- a/doc/vim/syntax/zig.vim +++ b/doc/vim/syntax/zig.vim @@ -16,7 +16,7 @@ syn keyword zigRepeat while for syn keyword zigConstant null undefined this syn keyword zigKeyword fn use test -syn keyword zigType bool f32 f64 void Unreachable type error +syn keyword zigType bool f32 f64 void noreturn type error syn keyword zigType i8 u8 i16 u16 i32 u32 i64 u64 isize usize syn keyword zigType c_short c_ushort c_int c_uint c_long c_ulong c_longlong c_ulonglong c_long_double diff --git a/src/all_types.hpp b/src/all_types.hpp index dc8c345285..a244e9abe0 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -334,6 +334,7 @@ enum NodeType { NodeTypeNullLiteral, NodeTypeUndefinedLiteral, NodeTypeThisLiteral, + NodeTypeUnreachable, NodeTypeIfBoolExpr, NodeTypeIfVarExpr, NodeTypeWhileExpr, @@ -758,6 +759,9 @@ struct AstNodeBreakExpr { struct AstNodeContinueExpr { }; +struct AstNodeUnreachableExpr { +}; + struct AstNodeArrayType { AstNode *size; @@ -827,6 +831,7 @@ struct AstNode { AstNodeBoolLiteral bool_literal; AstNodeBreakExpr break_expr; AstNodeContinueExpr continue_expr; + AstNodeUnreachableExpr unreachable_expr; AstNodeArrayType array_type; AstNodeErrorType error_type; AstNodeTypeLiteral type_literal; @@ -1173,7 +1178,6 @@ enum BuiltinFnId { BuiltinFnIdDivExact, BuiltinFnIdTruncate, BuiltinFnIdIntType, - BuiltinFnIdUnreachable, BuiltinFnIdSetFnVisible, BuiltinFnIdSetDebugSafety, BuiltinFnIdAlloca, diff --git a/src/analyze.cpp b/src/analyze.cpp index fca3b1e39f..1ba430be15 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -2110,6 +2110,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) { case NodeTypeGoto: case NodeTypeBreak: case NodeTypeContinue: + case NodeTypeUnreachable: case NodeTypeAsmExpr: case NodeTypeFieldAccessExpr: case NodeTypeStructField: diff --git a/src/ast_render.cpp b/src/ast_render.cpp index 9f3a1e143f..ed625560ef 100644 --- a/src/ast_render.cpp +++ b/src/ast_render.cpp @@ -216,6 +216,8 @@ static const char *node_type_str(NodeType node_type) { return "Break"; case NodeTypeContinue: return "Continue"; + case NodeTypeUnreachable: + return "Unreachable"; case NodeTypeAsmExpr: return "AsmExpr"; case NodeTypeFieldAccessExpr: @@ -890,6 +892,11 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { fprintf(ar->f, "continue"); break; } + case NodeTypeUnreachable: + { + fprintf(ar->f, "unreachable"); + break; + } case NodeTypeSliceExpr: { render_node_ungrouped(ar, node->data.slice_expr.array_ref_expr); diff --git a/src/codegen.cpp b/src/codegen.cpp index 94aec5664d..5dea908a11 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3786,7 +3786,7 @@ static void define_builtin_types(CodeGen *g) { TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdUnreachable); entry->type_ref = LLVMVoidType(); entry->zero_bits = true; - buf_init_from_str(&entry->name, "unreachable"); + buf_init_from_str(&entry->name, "noreturn"); entry->di_type = g->builtin_types.entry_void->di_type; g->builtin_types.entry_unreachable = entry; g->primitive_type_table.put(&entry->name, entry); @@ -4096,7 +4096,6 @@ static void define_builtin_fns(CodeGen *g) { create_builtin_fn(g, BuiltinFnIdCompileErr, "compileError", 1); create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX); create_builtin_fn(g, BuiltinFnIdIntType, "intType", 2); - create_builtin_fn(g, BuiltinFnIdUnreachable, "unreachable", 0); create_builtin_fn(g, BuiltinFnIdSetFnVisible, "setFnVisible", 2); create_builtin_fn(g, BuiltinFnIdSetDebugSafety, "setDebugSafety", 2); create_builtin_fn(g, BuiltinFnIdAlloca, "alloca", 2); diff --git a/src/ir.cpp b/src/ir.cpp index 73b09918fa..14fa780a40 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -3751,8 +3751,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo switch (builtin_fn->id) { case BuiltinFnIdInvalid: zig_unreachable(); - case BuiltinFnIdUnreachable: - return ir_build_unreachable(irb, scope, node); case BuiltinFnIdTypeof: { AstNode *arg_node = node->data.fn_call_expr.params.at(0); @@ -5467,6 +5465,8 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop return ir_lval_wrap(irb, scope, ir_gen_break(irb, scope, node), lval); case NodeTypeContinue: return ir_lval_wrap(irb, scope, ir_gen_continue(irb, scope, node), lval); + case NodeTypeUnreachable: + return ir_lval_wrap(irb, scope, ir_build_unreachable(irb, scope, node), lval); case NodeTypeDefer: return ir_lval_wrap(irb, scope, ir_gen_defer(irb, scope, node), lval); case NodeTypeSliceExpr: diff --git a/src/parser.cpp b/src/parser.cpp index 56b60e7e56..662ceba2c1 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -705,7 +705,7 @@ static AstNode *ast_parse_try_expr(ParseContext *pc, size_t *token_index, bool m /* PrimaryExpression = Number | String | CharLiteral | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | Symbol | ("@" Symbol FnCallExpression) | ArrayType | (option("extern") FnProto) | AsmExpression | ("error" "." Symbol) | ContainerDecl -KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "error" | "type" | "this" +KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "error" | "type" | "this" | "unreachable" */ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bool mandatory) { Token *token = &pc->tokens->at(*token_index); @@ -757,6 +757,10 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo AstNode *node = ast_create_node(pc, NodeTypeThisLiteral, token); *token_index += 1; return node; + } else if (token->id == TokenIdKeywordUnreachable) { + AstNode *node = ast_create_node(pc, NodeTypeUnreachable, token); + *token_index += 1; + return node; } else if (token->id == TokenIdKeywordType) { AstNode *node = ast_create_node(pc, NodeTypeTypeLiteral, token); *token_index += 1; @@ -2728,6 +2732,9 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont case NodeTypeContinue: // none break; + case NodeTypeUnreachable: + // none + break; case NodeTypeAsmExpr: for (size_t i = 0; i < node->data.asm_expr.input_list.length; i += 1) { AsmInput *asm_input = node->data.asm_expr.input_list.at(i); diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index 640cd1ffea..ca162d7e03 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -140,6 +140,7 @@ static const struct ZigKeyword zig_keywords[] = { {"type", TokenIdKeywordType}, {"undefined", TokenIdKeywordUndefined}, {"union", TokenIdKeywordUnion}, + {"unreachable", TokenIdKeywordUnreachable}, {"use", TokenIdKeywordUse}, {"var", TokenIdKeywordVar}, {"volatile", TokenIdKeywordVolatile}, @@ -1516,6 +1517,7 @@ const char * token_name(TokenId id) { case TokenIdKeywordType: return "type"; case TokenIdKeywordUndefined: return "undefined"; case TokenIdKeywordUnion: return "union"; + case TokenIdKeywordUnreachable: return "unreachable"; case TokenIdKeywordUse: return "use"; case TokenIdKeywordVar: return "var"; case TokenIdKeywordVolatile: return "volatile"; diff --git a/src/tokenizer.hpp b/src/tokenizer.hpp index 008bcde853..6b6d7ba891 100644 --- a/src/tokenizer.hpp +++ b/src/tokenizer.hpp @@ -81,6 +81,7 @@ enum TokenId { TokenIdKeywordType, TokenIdKeywordUndefined, TokenIdKeywordUnion, + TokenIdKeywordUnreachable, TokenIdKeywordUse, TokenIdKeywordVar, TokenIdKeywordVolatile, diff --git a/std/bootstrap.zig b/std/bootstrap.zig index 8a901419dd..e4e844b312 100644 --- a/std/bootstrap.zig +++ b/std/bootstrap.zig @@ -16,10 +16,10 @@ const exit = switch(@compileVar("os")) { var argc: usize = undefined; var argv: &&u8 = undefined; -export nakedcc fn _start() -> unreachable { +export nakedcc fn _start() -> noreturn { @setFnVisible(this, want_start_symbol); if (!want_start_symbol) { - @unreachable(); + unreachable; } switch (@compileVar("arch")) { @@ -45,7 +45,7 @@ fn callMain() -> %void { return root.main(args); } -fn callMainAndExit() -> unreachable { +fn callMainAndExit() -> noreturn { callMain() %% exit(1); exit(0); } @@ -53,7 +53,7 @@ fn callMainAndExit() -> unreachable { export fn main(c_argc: i32, c_argv: &&u8) -> i32 { @setFnVisible(this, want_main_symbol); if (!want_main_symbol) { - @unreachable(); + unreachable; } argc = usize(c_argc); diff --git a/std/builtin.zig b/std/builtin.zig index dfdad01abf..136cbd9da4 100644 --- a/std/builtin.zig +++ b/std/builtin.zig @@ -31,6 +31,6 @@ export fn memcpy(noalias dest: ?&u8, noalias src: ?&const u8, n: usize) { } // Avoid dragging in the debug safety mechanisms into this .o file. -pub fn panic(message: []const u8) -> unreachable { - @unreachable(); +pub fn panic(message: []const u8) -> noreturn { + unreachable; } diff --git a/std/c/index.zig b/std/c/index.zig index 84b54cfc8e..05ef9e4384 100644 --- a/std/c/index.zig +++ b/std/c/index.zig @@ -7,7 +7,7 @@ pub use switch(@compileVar("os")) { else => empty_import, }; -pub extern fn abort() -> unreachable; +pub extern fn abort() -> noreturn; const empty_import = @import("empty.zig"); diff --git a/std/compiler_rt.zig b/std/compiler_rt.zig index 255631a61f..f6e4c021d1 100644 --- a/std/compiler_rt.zig +++ b/std/compiler_rt.zig @@ -1,10 +1,10 @@ // Avoid dragging in the debug safety mechanisms into this .o file, // unless we're trying to test this file. -pub fn panic(message: []const u8) -> unreachable { +pub fn panic(message: []const u8) -> noreturn { if (@compileVar("is_test")) { @import("std").debug.panic(message); } else { - @unreachable(); + unreachable; } } @@ -259,7 +259,7 @@ export nakedcc fn __aeabi_uidivmod() { \\ add sp, sp, #4 \\ pop { pc } ::: "r2", "r1"); - @unreachable(); + unreachable; } @setFnVisible(this, false); @@ -511,5 +511,5 @@ fn test_one_udivsi3(a: su_int, b: su_int, expected_q: su_int) { fn assert(ok: bool) { - if (!ok) @unreachable(); + if (!ok) unreachable; } diff --git a/std/darwin.zig b/std/darwin.zig index 36a84bd73a..f5657b79b4 100644 --- a/std/darwin.zig +++ b/std/darwin.zig @@ -48,9 +48,9 @@ pub const SIGPWR = 30; pub const SIGSYS = 31; pub const SIGUNUSED = SIGSYS; -pub fn exit(status: usize) -> unreachable { +pub fn exit(status: usize) -> noreturn { _ = arch.syscall1(arch.SYS_exit, status); - @unreachable() + unreachable } /// Get the errno from a syscall return value, or 0 for no error. diff --git a/std/debug.zig b/std/debug.zig index 7fe1ef4d4b..42b4cc0f5d 100644 --- a/std/debug.zig +++ b/std/debug.zig @@ -10,12 +10,12 @@ error InvalidDebugInfo; error UnsupportedDebugInfo; pub fn assert(ok: bool) { - if (!ok) @unreachable() + if (!ok) unreachable } var panicking = false; /// This is the default panic implementation. -pub coldcc fn panic(message: []const u8) -> unreachable { +pub coldcc fn panic(message: []const u8) -> noreturn { // TODO // if (@atomicRmw(AtomicOp.XChg, &panicking, true, AtomicOrder.SeqCst)) { } if (panicking) { @@ -252,7 +252,7 @@ fn parseFormValueTargetAddrSize(in_stream: &io.InStream) -> %u64 { } else if (@sizeOf(usize) == 8) { %return in_stream.readIntLe(u64) } else { - @unreachable(); + unreachable; }; } diff --git a/std/fmt.zig b/std/fmt.zig index 1045737033..94a698e364 100644 --- a/std/fmt.zig +++ b/std/fmt.zig @@ -287,7 +287,7 @@ fn digitToChar(digit: u8, uppercase: bool) -> u8 { return switch (digit) { 0 ... 9 => digit + '0', 10 ... 35 => digit + ((if (uppercase) u8('A') else u8('a')) - 10), - else => @unreachable(), + else => unreachable, }; } @@ -316,9 +316,9 @@ fn bufPrintIntToSlice(buf: []u8, value: var, base: u8, uppercase: bool, width: u test "testParseU64DigitTooBig" { parseUnsigned(u64, "123a", 10) %% |err| { if (err == error.InvalidChar) return; - @unreachable(); + unreachable; }; - @unreachable(); + unreachable; } test "testParseUnsignedComptime" { diff --git a/std/hash_map.zig b/std/hash_map.zig index c22e3712a0..2e8da38b6d 100644 --- a/std/hash_map.zig +++ b/std/hash_map.zig @@ -50,7 +50,7 @@ pub fn HashMap(comptime K: type, comptime V: type, return entry; } } - @unreachable() // no next item + unreachable // no next item } }; @@ -125,9 +125,9 @@ pub fn HashMap(comptime K: type, comptime V: type, entry.distance_from_start_index -= 1; entry = next_entry; } - @unreachable() // shifting everything in the table + unreachable // shifting everything in the table }} - @unreachable() // key not found + unreachable // key not found } pub fn entryIterator(hm: &Self) -> Iterator { @@ -198,7 +198,7 @@ pub fn HashMap(comptime K: type, comptime V: type, }; return; } - @unreachable() // put into a full map + unreachable // put into a full map } fn internalGet(hm: &Self, key: K) -> ?&Entry { diff --git a/std/io.zig b/std/io.zig index 70c1d5b97d..1bc47ceffc 100644 --- a/std/io.zig +++ b/std/io.zig @@ -129,7 +129,7 @@ pub const OutStream = struct { if (write_err > 0) { return switch (write_err) { errno.EINTR => continue, - errno.EINVAL => @unreachable(), + errno.EINVAL => unreachable, errno.EDQUOT => error.DiskQuota, errno.EFBIG => error.FileTooBig, errno.EIO => error.Io, @@ -171,8 +171,8 @@ pub const InStream = struct { return switch (err) { errno.EINTR => continue, - errno.EFAULT => @unreachable(), - errno.EINVAL => @unreachable(), + errno.EFAULT => unreachable, + errno.EINVAL => unreachable, errno.EACCES => error.BadPerm, errno.EFBIG, errno.EOVERFLOW => error.FileTooBig, errno.EISDIR => error.IsDir, @@ -235,8 +235,8 @@ pub const InStream = struct { switch (read_err) { errno.EINTR => continue, - errno.EINVAL => @unreachable(), - errno.EFAULT => @unreachable(), + errno.EINVAL => unreachable, + errno.EFAULT => unreachable, errno.EBADF => return error.BadFd, errno.EIO => return error.Io, else => return error.Unexpected, diff --git a/std/linux.zig b/std/linux.zig index 5ace0d257d..9af7b1609d 100644 --- a/std/linux.zig +++ b/std/linux.zig @@ -297,9 +297,9 @@ pub fn lseek(fd: i32, offset: usize, ref_pos: usize) -> usize { arch.syscall3(arch.SYS_lseek, usize(fd), offset, ref_pos) } -pub fn exit(status: i32) -> unreachable { +pub fn exit(status: i32) -> noreturn { _ = arch.syscall1(arch.SYS_exit, usize(status)); - @unreachable() + unreachable } pub fn getrandom(buf: &u8, count: usize, flags: u32) -> usize { diff --git a/std/math.zig b/std/math.zig index 711e1de453..9bba820655 100644 --- a/std/math.zig +++ b/std/math.zig @@ -57,7 +57,7 @@ pub fn abs(x: var) -> @typeOf(x) { } else if (@isFloat(T)) { @compileError("TODO implement abs for floats"); } else { - @unreachable(); + unreachable; } } fn getReturnTypeForAbs(comptime T: type) -> type { diff --git a/std/net.zig b/std/net.zig index dfbe389424..50f63cbab9 100644 --- a/std/net.zig +++ b/std/net.zig @@ -21,8 +21,8 @@ const Connection = struct { const send_err = linux.getErrno(send_ret); switch (send_err) { 0 => return send_ret, - errno.EINVAL => @unreachable(), - errno.EFAULT => @unreachable(), + errno.EINVAL => unreachable, + errno.EFAULT => unreachable, errno.ECONNRESET => return error.ConnectionReset, errno.EINTR => return error.SigInterrupt, // TODO there are more possible errors @@ -35,8 +35,8 @@ const Connection = struct { const recv_err = linux.getErrno(recv_ret); switch (recv_err) { 0 => return buf[0...recv_ret], - errno.EINVAL => @unreachable(), - errno.EFAULT => @unreachable(), + errno.EINVAL => unreachable, + errno.EFAULT => unreachable, errno.ENOTSOCK => return error.NotSocket, errno.EINTR => return error.SigInterrupt, errno.ENOMEM => return error.NoMem, @@ -50,7 +50,7 @@ const Connection = struct { pub fn close(c: Connection) -> %void { switch (linux.getErrno(linux.close(c.socket_fd))) { 0 => return, - errno.EBADF => @unreachable(), + errno.EBADF => unreachable, errno.EINTR => return error.SigInterrupt, errno.EIO => return error.Io, else => return error.Unexpected, @@ -74,7 +74,7 @@ pub fn lookup(hostname: []const u8, out_addrs: []Address) -> %[]Address { // if (family != AF_INET) // buf[cnt++] = (struct address){ .family = AF_INET6, .addr = { [15] = 1 } }; // - @unreachable() // TODO + unreachable // TODO } // TODO @@ -86,7 +86,7 @@ pub fn lookup(hostname: []const u8, out_addrs: []Address) -> %[]Address { // else => {}, //}; - @unreachable() // TODO + unreachable // TODO } pub fn connectAddr(addr: &Address, port: u16) -> %Connection { @@ -114,7 +114,7 @@ pub fn connectAddr(addr: &Address, port: u16) -> %Connection { @memcpy(&os_addr.addr[0], &addr.addr[0], 16); linux.connect(socket_fd, (&linux.sockaddr)(&os_addr), @sizeOf(linux.sockaddr_in6)) } else { - @unreachable() + unreachable }; const connect_err = linux.getErrno(connect_ret); if (connect_err > 0) { @@ -324,11 +324,11 @@ fn parseIp4(buf: []const u8) -> %u32 { // @setFnTest(this); // // assert(%%parseIp4("127.0.0.1") == endian.swapIfLe(u32, 0x7f000001)); -// switch (parseIp4("256.0.0.1")) { Overflow => {}, else => @unreachable(), } -// switch (parseIp4("x.0.0.1")) { InvalidChar => {}, else => @unreachable(), } -// switch (parseIp4("127.0.0.1.1")) { JunkAtEnd => {}, else => @unreachable(), } -// switch (parseIp4("127.0.0.")) { Incomplete => {}, else => @unreachable(), } -// switch (parseIp4("100..0.1")) { InvalidChar => {}, else => @unreachable(), } +// switch (parseIp4("256.0.0.1")) { Overflow => {}, else => unreachable, } +// switch (parseIp4("x.0.0.1")) { InvalidChar => {}, else => unreachable, } +// switch (parseIp4("127.0.0.1.1")) { JunkAtEnd => {}, else => unreachable, } +// switch (parseIp4("127.0.0.")) { Incomplete => {}, else => unreachable, } +// switch (parseIp4("100..0.1")) { InvalidChar => {}, else => unreachable, } //} // //fn testParseIp6() { diff --git a/std/os.zig b/std/os.zig index b50aa021f9..68a52f5ff1 100644 --- a/std/os.zig +++ b/std/os.zig @@ -46,8 +46,8 @@ pub fn getRandomBytes(buf: []u8) -> %void { }; if (err > 0) { return switch (err) { - errno.EINVAL => @unreachable(), - errno.EFAULT => @unreachable(), + errno.EINVAL => unreachable, + errno.EFAULT => unreachable, errno.EINTR => continue, else => error.Unexpected, } @@ -59,7 +59,7 @@ pub fn getRandomBytes(buf: []u8) -> %void { /// Raises a signal in the current kernel thread, ending its execution. /// If linking against libc, this calls the abort() libc function. Otherwise /// it uses the zig standard library implementation. -pub coldcc fn abort() -> unreachable { +pub coldcc fn abort() -> noreturn { if (linking_libc) { c.abort(); } diff --git a/std/panic.zig b/std/panic.zig index 5be47b0c6e..9b58a4d9c8 100644 --- a/std/panic.zig +++ b/std/panic.zig @@ -3,7 +3,7 @@ // If this file wants to import other files *by name*, support for that would // have to be added in the compiler. -pub coldcc fn panic(message: []const u8) -> unreachable { +pub coldcc fn panic(message: []const u8) -> noreturn { if (@compileVar("os") == Os.freestanding) { while (true) {} } else { diff --git a/test/cases/enum.zig b/test/cases/enum.zig index 395a37caf1..4892ec6eba 100644 --- a/test/cases/enum.zig +++ b/test/cases/enum.zig @@ -16,7 +16,7 @@ test "enumType" { test "enumAsReturnValue" { switch (returnAnInt(13)) { Foo.One => |value| assert(value == 13), - else => @unreachable(), + else => unreachable, } } @@ -51,13 +51,13 @@ test "constantEnumWithPayload" { fn shouldBeEmpty(x: &const AnEnumWithPayload) { switch (*x) { AnEnumWithPayload.Empty => {}, - else => @unreachable(), + else => unreachable, } } fn shouldBeNotEmpty(x: &const AnEnumWithPayload) { switch (*x) { - AnEnumWithPayload.Empty => @unreachable(), + AnEnumWithPayload.Empty => unreachable, else => {}, } } diff --git a/test/cases/error.zig b/test/cases/error.zig index 27e45e9996..04a2c5099d 100644 --- a/test/cases/error.zig +++ b/test/cases/error.zig @@ -48,7 +48,7 @@ error AnError; error AnError; error SecondError; fn shouldBeNotEqual(a: error, b: error) { - if (a == b) @unreachable() + if (a == b) unreachable } diff --git a/test/cases/fn.zig b/test/cases/fn.zig index a58bf614f3..7dd1c1fc0a 100644 --- a/test/cases/fn.zig +++ b/test/cases/fn.zig @@ -13,7 +13,7 @@ test "localVariables" { } fn testLocVars(b: i32) { const a: i32 = 1; - if (a + b != 3) @unreachable(); + if (a + b != 3) unreachable; } @@ -72,8 +72,8 @@ test "implicitCastFnUnreachableReturn" { fn wantsFnWithVoid(f: fn()) { } -fn fnWithUnreachable() -> unreachable { - @unreachable() +fn fnWithUnreachable() -> noreturn { + unreachable } diff --git a/test/cases/for.zig b/test/cases/for.zig index f18b342fa2..76ef1f246d 100644 --- a/test/cases/for.zig +++ b/test/cases/for.zig @@ -12,7 +12,7 @@ test "continueInForLoop" { } break; } - if (sum != 6) @unreachable() + if (sum != 6) unreachable } test "forLoopWithPointerElemVar" { diff --git a/test/cases/goto.zig b/test/cases/goto.zig index b4a3af8adb..c09ec3f926 100644 --- a/test/cases/goto.zig +++ b/test/cases/goto.zig @@ -30,7 +30,7 @@ exit: if (it_worked) { return; } - @unreachable(); + unreachable; entry: defer it_worked = true; if (b) goto exit; diff --git a/test/cases/if.zig b/test/cases/if.zig index 7cff1c1a56..25efedda8d 100644 --- a/test/cases/if.zig +++ b/test/cases/if.zig @@ -6,20 +6,20 @@ test "ifStatements" { } fn shouldBeEqual(a: i32, b: i32) { if (a != b) { - @unreachable(); + unreachable; } else { return; } } fn firstEqlThird(a: i32, b: i32, c: i32) { if (a == b) { - @unreachable(); + unreachable; } else if (b == c) { - @unreachable(); + unreachable; } else if (a == c) { return; } else { - @unreachable(); + unreachable; } } diff --git a/test/cases/misc.zig b/test/cases/misc.zig index d78cd12d60..1c6d9853be 100644 --- a/test/cases/misc.zig +++ b/test/cases/misc.zig @@ -163,7 +163,7 @@ test "memcpyAndMemsetIntrinsics" { @memset(&foo[0], 'A', foo.len); @memcpy(&bar[0], &foo[0], bar.len); - if (bar[11] != 'A') @unreachable(); + if (bar[11] != 'A') unreachable; } test "builtinStaticEval" { @@ -178,13 +178,13 @@ test "slicing" { var slice = array[5...10]; - if (slice.len != 5) @unreachable(); + if (slice.len != 5) unreachable; const ptr = &slice[0]; - if (ptr[0] != 1234) @unreachable(); + if (ptr[0] != 1234) unreachable; var slice_rest = array[10...]; - if (slice_rest.len != 10) @unreachable(); + if (slice_rest.len != 10) unreachable; } @@ -344,7 +344,7 @@ fn test3_1(f: &const Test3Foo) { assert(pt.x == 3); assert(pt.y == 4); }, - else => @unreachable(), + else => unreachable, } } fn test3_2(f: &const Test3Foo) { @@ -352,7 +352,7 @@ fn test3_2(f: &const Test3Foo) { Test3Foo.Two => |x| { assert(x == 13); }, - else => @unreachable(), + else => unreachable, } } diff --git a/test/cases/null.zig b/test/cases/null.zig index 2194be28eb..94852f1555 100644 --- a/test/cases/null.zig +++ b/test/cases/null.zig @@ -7,10 +7,10 @@ test "nullableType" { if (y) { // OK } else { - @unreachable(); + unreachable; } } else { - @unreachable(); + unreachable; } const next_x : ?i32 = @generatedCode(null); @@ -21,7 +21,7 @@ test "nullableType" { const final_x : ?i32 = @generatedCode(13); - const num = final_x ?? @unreachable(); + const num = final_x ?? unreachable; assert(num == 13); } diff --git a/test/cases/switch.zig b/test/cases/switch.zig index 9f57f45fc8..4767631ce5 100644 --- a/test/cases/switch.zig +++ b/test/cases/switch.zig @@ -55,9 +55,9 @@ const Fruit = enum { }; fn nonConstSwitchOnEnum(fruit: Fruit) { switch (fruit) { - Fruit.Apple => @unreachable(), + Fruit.Apple => unreachable, Fruit.Orange => {}, - Fruit.Banana => @unreachable(), + Fruit.Banana => unreachable, } } @@ -72,7 +72,7 @@ fn nonConstSwitch(foo: SwitchStatmentFoo) { SwitchStatmentFoo.C => 3, SwitchStatmentFoo.D => 4, }; - if (val != 3) @unreachable(); + if (val != 3) unreachable; } const SwitchStatmentFoo = enum { A, @@ -95,10 +95,10 @@ const SwitchProngWithVarEnum = enum { fn switchProngWithVarFn(a: &const SwitchProngWithVarEnum) { switch(*a) { SwitchProngWithVarEnum.One => |x| { - if (x != 13) @unreachable(); + if (x != 13) unreachable; }, SwitchProngWithVarEnum.Two => |x| { - if (x != 13.0) @unreachable(); + if (x != 13.0) unreachable; }, SwitchProngWithVarEnum.Meh => |x| { const v: void = x; diff --git a/test/cases/try.zig b/test/cases/try.zig index e0c5793039..6979d36a2f 100644 --- a/test/cases/try.zig +++ b/test/cases/try.zig @@ -52,7 +52,7 @@ fn failIfTrue(ok: bool) -> %void { // @setFnTest(this); // // try (_ = failIfTrue(true)) { -// @unreachable(); +// unreachable; // } else |err| { // assert(err == error.ItBroke); // } diff --git a/test/run_tests.cpp b/test/run_tests.cpp index 27cbc6057b..8256881fea 100644 --- a/test/run_tests.cpp +++ b/test/run_tests.cpp @@ -471,8 +471,8 @@ const foo : i32 = 0; const c = @cImport(@cInclude("stdlib.h")); export fn compare_fn(a: ?&const c_void, b: ?&const c_void) -> c_int { - const a_int = (&i32)(a ?? @unreachable()); - const b_int = (&i32)(b ?? @unreachable()); + const a_int = (&i32)(a ?? unreachable); + const b_int = (&i32)(b ?? unreachable); if (*a_int < *b_int) { -1 } else if (*a_int > *b_int) { @@ -628,9 +628,9 @@ export fn entry() { a(); } )SOURCE", 1, ".tmp_source.zig:3:1: error: redefinition of 'a'"); add_compile_fail_case("unreachable with return", R"SOURCE( -fn a() -> unreachable {return;} +fn a() -> noreturn {return;} export fn entry() { a(); } - )SOURCE", 1, ".tmp_source.zig:2:24: error: expected type 'unreachable', found 'void'"); + )SOURCE", 1, ".tmp_source.zig:2:21: error: expected type 'noreturn', found 'void'"); add_compile_fail_case("control reaches end of non-void function", R"SOURCE( fn a() -> i32 {} @@ -656,7 +656,7 @@ export fn entry() { _ = a(); } )SOURCE", 1, ".tmp_source.zig:2:11: error: use of undeclared identifier 'bogus'"); add_compile_fail_case("pointer to unreachable", R"SOURCE( -fn a() -> &unreachable {} +fn a() -> &noreturn {} export fn entry() { _ = a(); } )SOURCE", 1, ".tmp_source.zig:2:12: error: pointer to unreachable not allowed"); @@ -724,14 +724,14 @@ export fn f() { add_compile_fail_case("unreachable variable", R"SOURCE( export fn f() { - const a : unreachable = {}; + const a: noreturn = {}; } - )SOURCE", 1, ".tmp_source.zig:3:15: error: variable of type 'unreachable' not allowed"); + )SOURCE", 1, ".tmp_source.zig:3:14: error: variable of type 'noreturn' not allowed"); add_compile_fail_case("unreachable parameter", R"SOURCE( -fn f(a : unreachable) {} +fn f(a: noreturn) {} export fn entry() { f(); } - )SOURCE", 1, ".tmp_source.zig:2:10: error: parameter of type 'unreachable' not allowed"); + )SOURCE", 1, ".tmp_source.zig:2:9: error: parameter of type 'noreturn' not allowed"); add_compile_fail_case("bad assignment target", R"SOURCE( export fn f() { @@ -1737,7 +1737,7 @@ export fn foo() { } fn assert(ok: bool) { - if (!ok) @unreachable(); + if (!ok) unreachable; } )SOURCE", 2, ".tmp_source.zig:11:14: error: unable to evaluate constant expression", @@ -1830,7 +1830,7 @@ export fn entry() { static void add_debug_safety_test_cases(void) { add_debug_safety_case("out of bounds slice access", R"SOURCE( -pub fn panic(message: []const u8) -> unreachable { +pub fn panic(message: []const u8) -> noreturn { @breakpoint(); while (true) {} } @@ -1845,7 +1845,7 @@ fn baz(a: i32) { } )SOURCE"); add_debug_safety_case("integer addition overflow", R"SOURCE( -pub fn panic(message: []const u8) -> unreachable { +pub fn panic(message: []const u8) -> noreturn { @breakpoint(); while (true) {} } @@ -1860,7 +1860,7 @@ fn add(a: u16, b: u16) -> u16 { )SOURCE"); add_debug_safety_case("integer subtraction overflow", R"SOURCE( -pub fn panic(message: []const u8) -> unreachable { +pub fn panic(message: []const u8) -> noreturn { @breakpoint(); while (true) {} } @@ -1875,7 +1875,7 @@ fn sub(a: u16, b: u16) -> u16 { )SOURCE"); add_debug_safety_case("integer multiplication overflow", R"SOURCE( -pub fn panic(message: []const u8) -> unreachable { +pub fn panic(message: []const u8) -> noreturn { @breakpoint(); while (true) {} } @@ -1890,7 +1890,7 @@ fn mul(a: u16, b: u16) -> u16 { )SOURCE"); add_debug_safety_case("integer negation overflow", R"SOURCE( -pub fn panic(message: []const u8) -> unreachable { +pub fn panic(message: []const u8) -> noreturn { @breakpoint(); while (true) {} } @@ -1905,7 +1905,7 @@ fn neg(a: i16) -> i16 { )SOURCE"); add_debug_safety_case("signed integer division overflow", R"SOURCE( -pub fn panic(message: []const u8) -> unreachable { +pub fn panic(message: []const u8) -> noreturn { @breakpoint(); while (true) {} } @@ -1920,7 +1920,7 @@ fn div(a: i16, b: i16) -> i16 { )SOURCE"); add_debug_safety_case("signed shift left overflow", R"SOURCE( -pub fn panic(message: []const u8) -> unreachable { +pub fn panic(message: []const u8) -> noreturn { @breakpoint(); while (true) {} } @@ -1935,7 +1935,7 @@ fn shl(a: i16, b: i16) -> i16 { )SOURCE"); add_debug_safety_case("unsigned shift left overflow", R"SOURCE( -pub fn panic(message: []const u8) -> unreachable { +pub fn panic(message: []const u8) -> noreturn { @breakpoint(); while (true) {} } @@ -1950,7 +1950,7 @@ fn shl(a: u16, b: u16) -> u16 { )SOURCE"); add_debug_safety_case("integer division by zero", R"SOURCE( -pub fn panic(message: []const u8) -> unreachable { +pub fn panic(message: []const u8) -> noreturn { @breakpoint(); while (true) {} } @@ -1964,7 +1964,7 @@ fn div0(a: i32, b: i32) -> i32 { )SOURCE"); add_debug_safety_case("exact division failure", R"SOURCE( -pub fn panic(message: []const u8) -> unreachable { +pub fn panic(message: []const u8) -> noreturn { @breakpoint(); while (true) {} } @@ -1979,7 +1979,7 @@ fn divExact(a: i32, b: i32) -> i32 { )SOURCE"); add_debug_safety_case("cast []u8 to bigger slice of wrong size", R"SOURCE( -pub fn panic(message: []const u8) -> unreachable { +pub fn panic(message: []const u8) -> noreturn { @breakpoint(); while (true) {} } @@ -1994,7 +1994,7 @@ fn widenSlice(slice: []const u8) -> []const i32 { )SOURCE"); add_debug_safety_case("value does not fit in shortening cast", R"SOURCE( -pub fn panic(message: []const u8) -> unreachable { +pub fn panic(message: []const u8) -> noreturn { @breakpoint(); while (true) {} } @@ -2009,7 +2009,7 @@ fn shorten_cast(x: i32) -> i8 { )SOURCE"); add_debug_safety_case("signed integer not fitting in cast to unsigned integer", R"SOURCE( -pub fn panic(message: []const u8) -> unreachable { +pub fn panic(message: []const u8) -> noreturn { @breakpoint(); while (true) {} } @@ -2024,7 +2024,7 @@ fn unsigned_cast(x: i32) -> u32 { )SOURCE"); add_debug_safety_case("unwrap error", R"SOURCE( -pub fn panic(message: []const u8) -> unreachable { +pub fn panic(message: []const u8) -> noreturn { @breakpoint(); while (true) {} } @@ -2055,7 +2055,7 @@ void baz(int8_t a, int16_t b, int32_t c, int64_t d); add_parseh_case("noreturn attribute", AllowWarningsNo, R"SOURCE( void foo(void) __attribute__((noreturn)); - )SOURCE", 1, R"OUTPUT(pub extern fn foo() -> unreachable;)OUTPUT"); + )SOURCE", 1, R"OUTPUT(pub extern fn foo() -> noreturn;)OUTPUT"); add_parseh_case("enums", AllowWarningsNo, R"SOURCE( enum Foo {