mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 14:25:16 +00:00
new unreachable syntax
* `noreturn` is the primitive type. * `unreachable` is a control flow keyword. * `@unreachable()` builtin function is deleted. closes #214
This commit is contained in:
parent
22e6bfca96
commit
451ce09067
@ -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.
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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";
|
||||
|
||||
@ -81,6 +81,7 @@ enum TokenId {
|
||||
TokenIdKeywordType,
|
||||
TokenIdKeywordUndefined,
|
||||
TokenIdKeywordUnion,
|
||||
TokenIdKeywordUnreachable,
|
||||
TokenIdKeywordUse,
|
||||
TokenIdKeywordVar,
|
||||
TokenIdKeywordVolatile,
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -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" {
|
||||
|
||||
@ -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 {
|
||||
|
||||
10
std/io.zig
10
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,
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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 {
|
||||
|
||||
26
std/net.zig
26
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() {
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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 => {},
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ error AnError;
|
||||
error AnError;
|
||||
error SecondError;
|
||||
fn shouldBeNotEqual(a: error, b: error) {
|
||||
if (a == b) @unreachable()
|
||||
if (a == b) unreachable
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@ test "continueInForLoop" {
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (sum != 6) @unreachable()
|
||||
if (sum != 6) unreachable
|
||||
}
|
||||
|
||||
test "forLoopWithPointerElemVar" {
|
||||
|
||||
@ -30,7 +30,7 @@ exit:
|
||||
if (it_worked) {
|
||||
return;
|
||||
}
|
||||
@unreachable();
|
||||
unreachable;
|
||||
entry:
|
||||
defer it_worked = true;
|
||||
if (b) goto exit;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -52,7 +52,7 @@ fn failIfTrue(ok: bool) -> %void {
|
||||
// @setFnTest(this);
|
||||
//
|
||||
// try (_ = failIfTrue(true)) {
|
||||
// @unreachable();
|
||||
// unreachable;
|
||||
// } else |err| {
|
||||
// assert(err == error.ItBroke);
|
||||
// }
|
||||
|
||||
@ -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 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user