authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-04-30 20:35:54-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-04-30 20:35:54-04:00
loga35b366eb64272c6d4646aedc035a837ed0c3cb0
treedcde18b655e59df2b24f6804eb069f3f43393b28
parent76ab1d2b6c9eedd861920ae6b6f8ee06aa482159

[breaking] delete ptr deref prefix op

start using zig-fmt-pointer-reform branch build of zig fmt to fix code to use the new syntax all of test/cases/* are processed, but there are more left to be done - all the std lib used by the behavior tests

49 files changed, 1694 insertions(+), 880 deletions(-)

src/all_types.hpp-1
...@@ -614,7 +614,6 @@ enum PrefixOp {...@@ -614,7 +614,6 @@ enum PrefixOp {
614 PrefixOpBinNot,614 PrefixOpBinNot,
615 PrefixOpNegation,615 PrefixOpNegation,
616 PrefixOpNegationWrap,616 PrefixOpNegationWrap,
617 PrefixOpDereference,
618 PrefixOpMaybe,617 PrefixOpMaybe,
619 PrefixOpUnwrapMaybe,618 PrefixOpUnwrapMaybe,
620};619};
src/ast_render.cpp-1
...@@ -66,7 +66,6 @@ static const char *prefix_op_str(PrefixOp prefix_op) {...@@ -66,7 +66,6 @@ static const char *prefix_op_str(PrefixOp prefix_op) {
66 case PrefixOpNegationWrap: return "-%";66 case PrefixOpNegationWrap: return "-%";
67 case PrefixOpBoolNot: return "!";67 case PrefixOpBoolNot: return "!";
68 case PrefixOpBinNot: return "~";68 case PrefixOpBinNot: return "~";
69 case PrefixOpDereference: return "*";
70 case PrefixOpMaybe: return "?";69 case PrefixOpMaybe: return "?";
71 case PrefixOpUnwrapMaybe: return "??";70 case PrefixOpUnwrapMaybe: return "??";
72 }71 }
src/ir.cpp-2
...@@ -4696,8 +4696,6 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod...@@ -4696,8 +4696,6 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod
4696 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegation), lval);4696 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegation), lval);
4697 case PrefixOpNegationWrap:4697 case PrefixOpNegationWrap:
4698 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegationWrap), lval);4698 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegationWrap), lval);
4699 case PrefixOpDereference:
4700 return ir_gen_prefix_op_id_lval(irb, scope, node, IrUnOpDereference, lval);
4701 case PrefixOpMaybe:4699 case PrefixOpMaybe:
4702 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpMaybe), lval);4700 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpMaybe), lval);
4703 case PrefixOpUnwrapMaybe:4701 case PrefixOpUnwrapMaybe:
src/parser.cpp+1-12
...@@ -1165,10 +1165,8 @@ static PrefixOp tok_to_prefix_op(Token *token) {...@@ -1165,10 +1165,8 @@ static PrefixOp tok_to_prefix_op(Token *token) {
1165 case TokenIdDash: return PrefixOpNegation;1165 case TokenIdDash: return PrefixOpNegation;
1166 case TokenIdMinusPercent: return PrefixOpNegationWrap;1166 case TokenIdMinusPercent: return PrefixOpNegationWrap;
1167 case TokenIdTilde: return PrefixOpBinNot;1167 case TokenIdTilde: return PrefixOpBinNot;
1168 case TokenIdStar: return PrefixOpDereference;
1169 case TokenIdMaybe: return PrefixOpMaybe;1168 case TokenIdMaybe: return PrefixOpMaybe;
1170 case TokenIdDoubleQuestion: return PrefixOpUnwrapMaybe;1169 case TokenIdDoubleQuestion: return PrefixOpUnwrapMaybe;
1171 case TokenIdStarStar: return PrefixOpDereference;
1172 default: return PrefixOpInvalid;1170 default: return PrefixOpInvalid;
1173 }1171 }
1174}1172}
...@@ -1214,7 +1212,7 @@ static AstNode *ast_parse_addr_of(ParseContext *pc, size_t *token_index) {...@@ -1214,7 +1212,7 @@ static AstNode *ast_parse_addr_of(ParseContext *pc, size_t *token_index) {
12141212
1215/*1213/*
1216PrefixOpExpression = PrefixOp ErrorSetExpr | SuffixOpExpression1214PrefixOpExpression = PrefixOp ErrorSetExpr | SuffixOpExpression
1217PrefixOp = "!" | "-" | "~" | "*" | ("&" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "??" | "-%" | "try" | "await"1215PrefixOp = "!" | "-" | "~" | ("*" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "??" | "-%" | "try" | "await"
1218*/1216*/
1219static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory) {1217static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
1220 Token *token = &pc->tokens->at(*token_index);1218 Token *token = &pc->tokens->at(*token_index);
...@@ -1237,15 +1235,6 @@ static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index,...@@ -1237,15 +1235,6 @@ static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index,
12371235
1238 AstNode *node = ast_create_node(pc, NodeTypePrefixOpExpr, token);1236 AstNode *node = ast_create_node(pc, NodeTypePrefixOpExpr, token);
1239 AstNode *parent_node = node;1237 AstNode *parent_node = node;
1240 if (token->id == TokenIdStarStar) {
1241 // pretend that we got 2 star tokens
1242
1243 parent_node = ast_create_node(pc, NodeTypePrefixOpExpr, token);
1244 parent_node->data.prefix_op_expr.primary_expr = node;
1245 parent_node->data.prefix_op_expr.prefix_op = PrefixOpDereference;
1246
1247 node->column += 1;
1248 }
12491238
1250 AstNode *prefix_op_expr = ast_parse_error_set_expr(pc, token_index, true);1239 AstNode *prefix_op_expr = ast_parse_error_set_expr(pc, token_index, true);
1251 node->data.prefix_op_expr.primary_expr = prefix_op_expr;1240 node->data.prefix_op_expr.primary_expr = prefix_op_expr;
src/translate_c.cpp+53-30
...@@ -247,6 +247,12 @@ static AstNode *trans_create_node_field_access_str(Context *c, AstNode *containe...@@ -247,6 +247,12 @@ static AstNode *trans_create_node_field_access_str(Context *c, AstNode *containe
247 return trans_create_node_field_access(c, container, buf_create_from_str(field_name));247 return trans_create_node_field_access(c, container, buf_create_from_str(field_name));
248}248}
249249
250static AstNode *trans_create_node_ptr_deref(Context *c, AstNode *child_node) {
251 AstNode *node = trans_create_node(c, NodeTypePtrDeref);
252 node->data.ptr_deref_expr.target = child_node;
253 return node;
254}
255
250static AstNode *trans_create_node_prefix_op(Context *c, PrefixOp op, AstNode *child_node) {256static AstNode *trans_create_node_prefix_op(Context *c, PrefixOp op, AstNode *child_node) {
251 AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);257 AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);
252 node->data.prefix_op_expr.prefix_op = op;258 node->data.prefix_op_expr.prefix_op = op;
...@@ -1412,8 +1418,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result...@@ -1412,8 +1418,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result
1412 AstNode *operation_type_cast = trans_c_cast(c, rhs_location,1418 AstNode *operation_type_cast = trans_c_cast(c, rhs_location,
1413 stmt->getComputationLHSType(),1419 stmt->getComputationLHSType(),
1414 stmt->getLHS()->getType(),1420 stmt->getLHS()->getType(),
1415 trans_create_node_prefix_op(c, PrefixOpDereference,1421 trans_create_node_ptr_deref(c, trans_create_node_symbol(c, tmp_var_name)));
1416 trans_create_node_symbol(c, tmp_var_name)));
14171422
1418 // result_type(... >> u5(rhs))1423 // result_type(... >> u5(rhs))
1419 AstNode *result_type_cast = trans_c_cast(c, rhs_location,1424 AstNode *result_type_cast = trans_c_cast(c, rhs_location,
...@@ -1426,7 +1431,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result...@@ -1426,7 +1431,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result
14261431
1427 // *_ref = ...1432 // *_ref = ...
1428 AstNode *assign_statement = trans_create_node_bin_op(c,1433 AstNode *assign_statement = trans_create_node_bin_op(c,
1429 trans_create_node_prefix_op(c, PrefixOpDereference,1434 trans_create_node_ptr_deref(c,
1430 trans_create_node_symbol(c, tmp_var_name)),1435 trans_create_node_symbol(c, tmp_var_name)),
1431 BinOpTypeAssign, result_type_cast);1436 BinOpTypeAssign, result_type_cast);
14321437
...@@ -1436,7 +1441,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result...@@ -1436,7 +1441,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result
1436 // break :x *_ref1441 // break :x *_ref
1437 child_scope->node->data.block.statements.append(1442 child_scope->node->data.block.statements.append(
1438 trans_create_node_break(c, label_name,1443 trans_create_node_break(c, label_name,
1439 trans_create_node_prefix_op(c, PrefixOpDereference,1444 trans_create_node_ptr_deref(c,
1440 trans_create_node_symbol(c, tmp_var_name))));1445 trans_create_node_symbol(c, tmp_var_name))));
1441 }1446 }
14421447
...@@ -1483,11 +1488,11 @@ static AstNode *trans_create_compound_assign(Context *c, ResultUsed result_used,...@@ -1483,11 +1488,11 @@ static AstNode *trans_create_compound_assign(Context *c, ResultUsed result_used,
1483 if (rhs == nullptr) return nullptr;1488 if (rhs == nullptr) return nullptr;
14841489
1485 AstNode *assign_statement = trans_create_node_bin_op(c,1490 AstNode *assign_statement = trans_create_node_bin_op(c,
1486 trans_create_node_prefix_op(c, PrefixOpDereference,1491 trans_create_node_ptr_deref(c,
1487 trans_create_node_symbol(c, tmp_var_name)),1492 trans_create_node_symbol(c, tmp_var_name)),
1488 BinOpTypeAssign,1493 BinOpTypeAssign,
1489 trans_create_node_bin_op(c,1494 trans_create_node_bin_op(c,
1490 trans_create_node_prefix_op(c, PrefixOpDereference,1495 trans_create_node_ptr_deref(c,
1491 trans_create_node_symbol(c, tmp_var_name)),1496 trans_create_node_symbol(c, tmp_var_name)),
1492 bin_op,1497 bin_op,
1493 rhs));1498 rhs));
...@@ -1496,7 +1501,7 @@ static AstNode *trans_create_compound_assign(Context *c, ResultUsed result_used,...@@ -1496,7 +1501,7 @@ static AstNode *trans_create_compound_assign(Context *c, ResultUsed result_used,
1496 // break :x *_ref1501 // break :x *_ref
1497 child_scope->node->data.block.statements.append(1502 child_scope->node->data.block.statements.append(
1498 trans_create_node_break(c, label_name,1503 trans_create_node_break(c, label_name,
1499 trans_create_node_prefix_op(c, PrefixOpDereference,1504 trans_create_node_ptr_deref(c,
1500 trans_create_node_symbol(c, tmp_var_name))));1505 trans_create_node_symbol(c, tmp_var_name))));
15011506
1502 return child_scope->node;1507 return child_scope->node;
...@@ -1817,13 +1822,13 @@ static AstNode *trans_create_post_crement(Context *c, ResultUsed result_used, Tr...@@ -1817,13 +1822,13 @@ static AstNode *trans_create_post_crement(Context *c, ResultUsed result_used, Tr
1817 // const _tmp = *_ref;1822 // const _tmp = *_ref;
1818 Buf* tmp_var_name = buf_create_from_str("_tmp");1823 Buf* tmp_var_name = buf_create_from_str("_tmp");
1819 AstNode *tmp_var_decl = trans_create_node_var_decl_local(c, true, tmp_var_name, nullptr,1824 AstNode *tmp_var_decl = trans_create_node_var_decl_local(c, true, tmp_var_name, nullptr,
1820 trans_create_node_prefix_op(c, PrefixOpDereference,1825 trans_create_node_ptr_deref(c,
1821 trans_create_node_symbol(c, ref_var_name)));1826 trans_create_node_symbol(c, ref_var_name)));
1822 child_scope->node->data.block.statements.append(tmp_var_decl);1827 child_scope->node->data.block.statements.append(tmp_var_decl);
18231828
1824 // *_ref += 1;1829 // *_ref += 1;
1825 AstNode *assign_statement = trans_create_node_bin_op(c,1830 AstNode *assign_statement = trans_create_node_bin_op(c,
1826 trans_create_node_prefix_op(c, PrefixOpDereference,1831 trans_create_node_ptr_deref(c,
1827 trans_create_node_symbol(c, ref_var_name)),1832 trans_create_node_symbol(c, ref_var_name)),
1828 assign_op,1833 assign_op,
1829 trans_create_node_unsigned(c, 1));1834 trans_create_node_unsigned(c, 1));
...@@ -1871,14 +1876,14 @@ static AstNode *trans_create_pre_crement(Context *c, ResultUsed result_used, Tra...@@ -1871,14 +1876,14 @@ static AstNode *trans_create_pre_crement(Context *c, ResultUsed result_used, Tra
18711876
1872 // *_ref += 1;1877 // *_ref += 1;
1873 AstNode *assign_statement = trans_create_node_bin_op(c,1878 AstNode *assign_statement = trans_create_node_bin_op(c,
1874 trans_create_node_prefix_op(c, PrefixOpDereference,1879 trans_create_node_ptr_deref(c,
1875 trans_create_node_symbol(c, ref_var_name)),1880 trans_create_node_symbol(c, ref_var_name)),
1876 assign_op,1881 assign_op,
1877 trans_create_node_unsigned(c, 1));1882 trans_create_node_unsigned(c, 1));
1878 child_scope->node->data.block.statements.append(assign_statement);1883 child_scope->node->data.block.statements.append(assign_statement);
18791884
1880 // break :x *_ref1885 // break :x *_ref
1881 AstNode *deref_expr = trans_create_node_prefix_op(c, PrefixOpDereference,1886 AstNode *deref_expr = trans_create_node_ptr_deref(c,
1882 trans_create_node_symbol(c, ref_var_name));1887 trans_create_node_symbol(c, ref_var_name));
1883 child_scope->node->data.block.statements.append(trans_create_node_break(c, label_name, deref_expr));1888 child_scope->node->data.block.statements.append(trans_create_node_break(c, label_name, deref_expr));
18841889
...@@ -1923,7 +1928,7 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc...@@ -1923,7 +1928,7 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc
1923 if (is_fn_ptr)1928 if (is_fn_ptr)
1924 return value_node;1929 return value_node;
1925 AstNode *unwrapped = trans_create_node_prefix_op(c, PrefixOpUnwrapMaybe, value_node);1930 AstNode *unwrapped = trans_create_node_prefix_op(c, PrefixOpUnwrapMaybe, value_node);
1926 return trans_create_node_prefix_op(c, PrefixOpDereference, unwrapped);1931 return trans_create_node_ptr_deref(c, unwrapped);
1927 }1932 }
1928 case UO_Plus:1933 case UO_Plus:
1929 emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_Plus");1934 emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_Plus");
...@@ -4469,27 +4474,45 @@ static AstNode *parse_ctok_suffix_op_expr(Context *c, CTokenize *ctok, size_t *t...@@ -4469,27 +4474,45 @@ static AstNode *parse_ctok_suffix_op_expr(Context *c, CTokenize *ctok, size_t *t
4469 }4474 }
4470}4475}
44714476
4472static PrefixOp ctok_to_prefix_op(CTok *token) {
4473 switch (token->id) {
4474 case CTokIdBang: return PrefixOpBoolNot;
4475 case CTokIdMinus: return PrefixOpNegation;
4476 case CTokIdTilde: return PrefixOpBinNot;
4477 case CTokIdAsterisk: return PrefixOpDereference;
4478 default: return PrefixOpInvalid;
4479 }
4480}
4481static AstNode *parse_ctok_prefix_op_expr(Context *c, CTokenize *ctok, size_t *tok_i) {4477static AstNode *parse_ctok_prefix_op_expr(Context *c, CTokenize *ctok, size_t *tok_i) {
4482 CTok *op_tok = &ctok->tokens.at(*tok_i);4478 CTok *op_tok = &ctok->tokens.at(*tok_i);
4483 PrefixOp prefix_op = ctok_to_prefix_op(op_tok);
4484 if (prefix_op == PrefixOpInvalid) {
4485 return parse_ctok_suffix_op_expr(c, ctok, tok_i);
4486 }
4487 *tok_i += 1;
44884479
4489 AstNode *prefix_op_expr = parse_ctok_prefix_op_expr(c, ctok, tok_i);4480 switch (op_tok->id) {
4490 if (prefix_op_expr == nullptr)4481 case CTokIdBang:
4491 return nullptr;4482 {
4492 return trans_create_node_prefix_op(c, prefix_op, prefix_op_expr);4483 *tok_i += 1;
4484 AstNode *prefix_op_expr = parse_ctok_prefix_op_expr(c, ctok, tok_i);
4485 if (prefix_op_expr == nullptr)
4486 return nullptr;
4487 return trans_create_node_prefix_op(c, PrefixOpBoolNot, prefix_op_expr);
4488 }
4489 case CTokIdMinus:
4490 {
4491 *tok_i += 1;
4492 AstNode *prefix_op_expr = parse_ctok_prefix_op_expr(c, ctok, tok_i);
4493 if (prefix_op_expr == nullptr)
4494 return nullptr;
4495 return trans_create_node_prefix_op(c, PrefixOpNegation, prefix_op_expr);
4496 }
4497 case CTokIdTilde:
4498 {
4499 *tok_i += 1;
4500 AstNode *prefix_op_expr = parse_ctok_prefix_op_expr(c, ctok, tok_i);
4501 if (prefix_op_expr == nullptr)
4502 return nullptr;
4503 return trans_create_node_prefix_op(c, PrefixOpBinNot, prefix_op_expr);
4504 }
4505 case CTokIdAsterisk:
4506 {
4507 *tok_i += 1;
4508 AstNode *prefix_op_expr = parse_ctok_prefix_op_expr(c, ctok, tok_i);
4509 if (prefix_op_expr == nullptr)
4510 return nullptr;
4511 return trans_create_node_ptr_deref(c, prefix_op_expr);
4512 }
4513 default:
4514 return parse_ctok_suffix_op_expr(c, ctok, tok_i);
4515 }
4493}4516}
44944517
4495static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *char_ptr) {4518static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *char_ptr) {
std/debug/index.zig+98-135
...@@ -104,9 +104,7 @@ pub fn panic(comptime format: []const u8, args: ...) noreturn {...@@ -104,9 +104,7 @@ pub fn panic(comptime format: []const u8, args: ...) noreturn {
104104
105var panicking: u8 = 0; // TODO make this a bool105var panicking: u8 = 0; // TODO make this a bool
106106
107pub fn panicExtra(trace: ?&const builtin.StackTrace, first_trace_addr: ?usize,107pub fn panicExtra(trace: ?&const builtin.StackTrace, first_trace_addr: ?usize, comptime format: []const u8, args: ...) noreturn {
108 comptime format: []const u8, args: ...) noreturn
109{
110 @setCold(true);108 @setCold(true);
111109
112 if (@atomicRmw(u8, &panicking, builtin.AtomicRmwOp.Xchg, 1, builtin.AtomicOrder.SeqCst) == 1) {110 if (@atomicRmw(u8, &panicking, builtin.AtomicRmwOp.Xchg, 1, builtin.AtomicOrder.SeqCst) == 1) {
...@@ -132,9 +130,7 @@ const WHITE = "\x1b[37;1m";...@@ -132,9 +130,7 @@ const WHITE = "\x1b[37;1m";
132const DIM = "\x1b[2m";130const DIM = "\x1b[2m";
133const RESET = "\x1b[0m";131const RESET = "\x1b[0m";
134132
135pub fn writeStackTrace(stack_trace: &const builtin.StackTrace, out_stream: var, allocator: &mem.Allocator,133pub fn writeStackTrace(stack_trace: &const builtin.StackTrace, out_stream: var, allocator: &mem.Allocator, debug_info: &ElfStackTrace, tty_color: bool) !void {
136 debug_info: &ElfStackTrace, tty_color: bool) !void
137{
138 var frame_index: usize = undefined;134 var frame_index: usize = undefined;
139 var frames_left: usize = undefined;135 var frames_left: usize = undefined;
140 if (stack_trace.index < stack_trace.instruction_addresses.len) {136 if (stack_trace.index < stack_trace.instruction_addresses.len) {
...@@ -154,9 +150,7 @@ pub fn writeStackTrace(stack_trace: &const builtin.StackTrace, out_stream: var,...@@ -154,9 +150,7 @@ pub fn writeStackTrace(stack_trace: &const builtin.StackTrace, out_stream: var,
154 }150 }
155}151}
156152
157pub fn writeCurrentStackTrace(out_stream: var, allocator: &mem.Allocator,153pub fn writeCurrentStackTrace(out_stream: var, allocator: &mem.Allocator, debug_info: &ElfStackTrace, tty_color: bool, start_addr: ?usize) !void {
158 debug_info: &ElfStackTrace, tty_color: bool, start_addr: ?usize) !void
159{
160 const AddressState = union(enum) {154 const AddressState = union(enum) {
161 NotLookingForStartAddress,155 NotLookingForStartAddress,
162 LookingForStartAddress: usize,156 LookingForStartAddress: usize,
...@@ -166,14 +160,14 @@ pub fn writeCurrentStackTrace(out_stream: var, allocator: &mem.Allocator,...@@ -166,14 +160,14 @@ pub fn writeCurrentStackTrace(out_stream: var, allocator: &mem.Allocator,
166 // else AddressState.NotLookingForStartAddress;160 // else AddressState.NotLookingForStartAddress;
167 var addr_state: AddressState = undefined;161 var addr_state: AddressState = undefined;
168 if (start_addr) |addr| {162 if (start_addr) |addr| {
169 addr_state = AddressState { .LookingForStartAddress = addr };163 addr_state = AddressState{ .LookingForStartAddress = addr };
170 } else {164 } else {
171 addr_state = AddressState.NotLookingForStartAddress;165 addr_state = AddressState.NotLookingForStartAddress;
172 }166 }
173167
174 var fp = @ptrToInt(@frameAddress());168 var fp = @ptrToInt(@frameAddress());
175 while (fp != 0) : (fp = *@intToPtr(&const usize, fp)) {169 while (fp != 0) : (fp = @intToPtr(&const usize, fp).*) {
176 const return_address = *@intToPtr(&const usize, fp + @sizeOf(usize));170 const return_address = @intToPtr(&const usize, fp + @sizeOf(usize)).*;
177171
178 switch (addr_state) {172 switch (addr_state) {
179 AddressState.NotLookingForStartAddress => {},173 AddressState.NotLookingForStartAddress => {},
...@@ -200,32 +194,32 @@ fn printSourceAtAddress(debug_info: &ElfStackTrace, out_stream: var, address: us...@@ -200,32 +194,32 @@ fn printSourceAtAddress(debug_info: &ElfStackTrace, out_stream: var, address: us
200 // in practice because the compiler dumps everything in a single194 // in practice because the compiler dumps everything in a single
201 // object file. Future improvement: use external dSYM data when195 // object file. Future improvement: use external dSYM data when
202 // available.196 // available.
203 const unknown = macho.Symbol { .name = "???", .address = address };197 const unknown = macho.Symbol{
198 .name = "???",
199 .address = address,
200 };
204 const symbol = debug_info.symbol_table.search(address) ?? &unknown;201 const symbol = debug_info.symbol_table.search(address) ?? &unknown;
205 try out_stream.print(WHITE ++ "{}" ++ RESET ++ ": " ++202 try out_stream.print(WHITE ++ "{}" ++ RESET ++ ": " ++ DIM ++ ptr_hex ++ " in ??? (???)" ++ RESET ++ "\n", symbol.name, address);
206 DIM ++ ptr_hex ++ " in ??? (???)" ++ RESET ++ "\n",
207 symbol.name, address);
208 },203 },
209 else => {204 else => {
210 const compile_unit = findCompileUnit(debug_info, address) catch {205 const compile_unit = findCompileUnit(debug_info, address) catch {
211 try out_stream.print("???:?:?: " ++ DIM ++ ptr_hex ++ " in ??? (???)" ++ RESET ++ "\n ???\n\n",206 try out_stream.print("???:?:?: " ++ DIM ++ ptr_hex ++ " in ??? (???)" ++ RESET ++ "\n ???\n\n", address);
212 address);
213 return;207 return;
214 };208 };
215 const compile_unit_name = try compile_unit.die.getAttrString(debug_info, DW.AT_name);209 const compile_unit_name = try compile_unit.die.getAttrString(debug_info, DW.AT_name);
216 if (getLineNumberInfo(debug_info, compile_unit, address - 1)) |line_info| {210 if (getLineNumberInfo(debug_info, compile_unit, address - 1)) |line_info| {
217 defer line_info.deinit();211 defer line_info.deinit();
218 try out_stream.print(WHITE ++ "{}:{}:{}" ++ RESET ++ ": " ++212 try out_stream.print(WHITE ++ "{}:{}:{}" ++ RESET ++ ": " ++ DIM ++ ptr_hex ++ " in ??? ({})" ++ RESET ++ "\n", line_info.file_name, line_info.line, line_info.column, address, compile_unit_name);
219 DIM ++ ptr_hex ++ " in ??? ({})" ++ RESET ++ "\n",
220 line_info.file_name, line_info.line, line_info.column,
221 address, compile_unit_name);
222 if (printLineFromFile(debug_info.allocator(), out_stream, line_info)) {213 if (printLineFromFile(debug_info.allocator(), out_stream, line_info)) {
223 if (line_info.column == 0) {214 if (line_info.column == 0) {
224 try out_stream.write("\n");215 try out_stream.write("\n");
225 } else {216 } else {
226 {var col_i: usize = 1; while (col_i < line_info.column) : (col_i += 1) {217 {
227 try out_stream.writeByte(' ');218 var col_i: usize = 1;
228 }}219 while (col_i < line_info.column) : (col_i += 1) {
220 try out_stream.writeByte(' ');
221 }
222 }
229 try out_stream.write(GREEN ++ "^" ++ RESET ++ "\n");223 try out_stream.write(GREEN ++ "^" ++ RESET ++ "\n");
230 }224 }
231 } else |err| switch (err) {225 } else |err| switch (err) {
...@@ -233,7 +227,8 @@ fn printSourceAtAddress(debug_info: &ElfStackTrace, out_stream: var, address: us...@@ -233,7 +227,8 @@ fn printSourceAtAddress(debug_info: &ElfStackTrace, out_stream: var, address: us
233 else => return err,227 else => return err,
234 }228 }
235 } else |err| switch (err) {229 } else |err| switch (err) {
236 error.MissingDebugInfo, error.InvalidDebugInfo => {230 error.MissingDebugInfo,
231 error.InvalidDebugInfo => {
237 try out_stream.print(ptr_hex ++ " in ??? ({})\n", address, compile_unit_name);232 try out_stream.print(ptr_hex ++ " in ??? ({})\n", address, compile_unit_name);
238 },233 },
239 else => return err,234 else => return err,
...@@ -247,7 +242,7 @@ pub fn openSelfDebugInfo(allocator: &mem.Allocator) !&ElfStackTrace {...@@ -247,7 +242,7 @@ pub fn openSelfDebugInfo(allocator: &mem.Allocator) !&ElfStackTrace {
247 builtin.ObjectFormat.elf => {242 builtin.ObjectFormat.elf => {
248 const st = try allocator.create(ElfStackTrace);243 const st = try allocator.create(ElfStackTrace);
249 errdefer allocator.destroy(st);244 errdefer allocator.destroy(st);
250 *st = ElfStackTrace {245 st.* = ElfStackTrace{
251 .self_exe_file = undefined,246 .self_exe_file = undefined,
252 .elf = undefined,247 .elf = undefined,
253 .debug_info = undefined,248 .debug_info = undefined,
...@@ -279,9 +274,7 @@ pub fn openSelfDebugInfo(allocator: &mem.Allocator) !&ElfStackTrace {...@@ -279,9 +274,7 @@ pub fn openSelfDebugInfo(allocator: &mem.Allocator) !&ElfStackTrace {
279 const st = try allocator.create(ElfStackTrace);274 const st = try allocator.create(ElfStackTrace);
280 errdefer allocator.destroy(st);275 errdefer allocator.destroy(st);
281276
282 *st = ElfStackTrace {277 st.* = ElfStackTrace{ .symbol_table = try macho.loadSymbols(allocator, &io.FileInStream.init(&exe_file)) };
283 .symbol_table = try macho.loadSymbols(allocator, &io.FileInStream.init(&exe_file)),
284 };
285278
286 return st;279 return st;
287 },280 },
...@@ -325,8 +318,7 @@ fn printLineFromFile(allocator: &mem.Allocator, out_stream: var, line_info: &con...@@ -325,8 +318,7 @@ fn printLineFromFile(allocator: &mem.Allocator, out_stream: var, line_info: &con
325 }318 }
326 }319 }
327320
328 if (amt_read < buf.len)321 if (amt_read < buf.len) return error.EndOfFile;
329 return error.EndOfFile;
330 }322 }
331}323}
332324
...@@ -418,10 +410,8 @@ const Constant = struct {...@@ -418,10 +410,8 @@ const Constant = struct {
418 signed: bool,410 signed: bool,
419411
420 fn asUnsignedLe(self: &const Constant) !u64 {412 fn asUnsignedLe(self: &const Constant) !u64 {
421 if (self.payload.len > @sizeOf(u64))413 if (self.payload.len > @sizeOf(u64)) return error.InvalidDebugInfo;
422 return error.InvalidDebugInfo;414 if (self.signed) return error.InvalidDebugInfo;
423 if (self.signed)
424 return error.InvalidDebugInfo;
425 return mem.readInt(self.payload, u64, builtin.Endian.Little);415 return mem.readInt(self.payload, u64, builtin.Endian.Little);
426 }416 }
427};417};
...@@ -438,15 +428,14 @@ const Die = struct {...@@ -438,15 +428,14 @@ const Die = struct {
438428
439 fn getAttr(self: &const Die, id: u64) ?&const FormValue {429 fn getAttr(self: &const Die, id: u64) ?&const FormValue {
440 for (self.attrs.toSliceConst()) |*attr| {430 for (self.attrs.toSliceConst()) |*attr| {
441 if (attr.id == id)431 if (attr.id == id) return &attr.value;
442 return &attr.value;
443 }432 }
444 return null;433 return null;
445 }434 }
446435
447 fn getAttrAddr(self: &const Die, id: u64) !u64 {436 fn getAttrAddr(self: &const Die, id: u64) !u64 {
448 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;437 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
449 return switch (*form_value) {438 return switch (form_value.*) {
450 FormValue.Address => |value| value,439 FormValue.Address => |value| value,
451 else => error.InvalidDebugInfo,440 else => error.InvalidDebugInfo,
452 };441 };
...@@ -454,7 +443,7 @@ const Die = struct {...@@ -454,7 +443,7 @@ const Die = struct {
454443
455 fn getAttrSecOffset(self: &const Die, id: u64) !u64 {444 fn getAttrSecOffset(self: &const Die, id: u64) !u64 {
456 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;445 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
457 return switch (*form_value) {446 return switch (form_value.*) {
458 FormValue.Const => |value| value.asUnsignedLe(),447 FormValue.Const => |value| value.asUnsignedLe(),
459 FormValue.SecOffset => |value| value,448 FormValue.SecOffset => |value| value,
460 else => error.InvalidDebugInfo,449 else => error.InvalidDebugInfo,
...@@ -463,7 +452,7 @@ const Die = struct {...@@ -463,7 +452,7 @@ const Die = struct {
463452
464 fn getAttrUnsignedLe(self: &const Die, id: u64) !u64 {453 fn getAttrUnsignedLe(self: &const Die, id: u64) !u64 {
465 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;454 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
466 return switch (*form_value) {455 return switch (form_value.*) {
467 FormValue.Const => |value| value.asUnsignedLe(),456 FormValue.Const => |value| value.asUnsignedLe(),
468 else => error.InvalidDebugInfo,457 else => error.InvalidDebugInfo,
469 };458 };
...@@ -471,7 +460,7 @@ const Die = struct {...@@ -471,7 +460,7 @@ const Die = struct {
471460
472 fn getAttrString(self: &const Die, st: &ElfStackTrace, id: u64) ![]u8 {461 fn getAttrString(self: &const Die, st: &ElfStackTrace, id: u64) ![]u8 {
473 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;462 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
474 return switch (*form_value) {463 return switch (form_value.*) {
475 FormValue.String => |value| value,464 FormValue.String => |value| value,
476 FormValue.StrPtr => |offset| getString(st, offset),465 FormValue.StrPtr => |offset| getString(st, offset),
477 else => error.InvalidDebugInfo,466 else => error.InvalidDebugInfo,
...@@ -518,10 +507,8 @@ const LineNumberProgram = struct {...@@ -518,10 +507,8 @@ const LineNumberProgram = struct {
518 prev_basic_block: bool,507 prev_basic_block: bool,
519 prev_end_sequence: bool,508 prev_end_sequence: bool,
520509
521 pub fn init(is_stmt: bool, include_dirs: []const []const u8,510 pub fn init(is_stmt: bool, include_dirs: []const []const u8, file_entries: &ArrayList(FileEntry), target_address: usize) LineNumberProgram {
522 file_entries: &ArrayList(FileEntry), target_address: usize) LineNumberProgram511 return LineNumberProgram{
523 {
524 return LineNumberProgram {
525 .address = 0,512 .address = 0,
526 .file = 1,513 .file = 1,
527 .line = 1,514 .line = 1,
...@@ -548,14 +535,16 @@ const LineNumberProgram = struct {...@@ -548,14 +535,16 @@ const LineNumberProgram = struct {
548 return error.MissingDebugInfo;535 return error.MissingDebugInfo;
549 } else if (self.prev_file - 1 >= self.file_entries.len) {536 } else if (self.prev_file - 1 >= self.file_entries.len) {
550 return error.InvalidDebugInfo;537 return error.InvalidDebugInfo;
551 } else &self.file_entries.items[self.prev_file - 1];538 } else
539 &self.file_entries.items[self.prev_file - 1];
552540
553 const dir_name = if (file_entry.dir_index >= self.include_dirs.len) {541 const dir_name = if (file_entry.dir_index >= self.include_dirs.len) {
554 return error.InvalidDebugInfo;542 return error.InvalidDebugInfo;
555 } else self.include_dirs[file_entry.dir_index];543 } else
544 self.include_dirs[file_entry.dir_index];
556 const file_name = try os.path.join(self.file_entries.allocator, dir_name, file_entry.file_name);545 const file_name = try os.path.join(self.file_entries.allocator, dir_name, file_entry.file_name);
557 errdefer self.file_entries.allocator.free(file_name);546 errdefer self.file_entries.allocator.free(file_name);
558 return LineInfo {547 return LineInfo{
559 .line = if (self.prev_line >= 0) usize(self.prev_line) else 0,548 .line = if (self.prev_line >= 0) usize(self.prev_line) else 0,
560 .column = self.prev_column,549 .column = self.prev_column,
561 .file_name = file_name,550 .file_name = file_name,
...@@ -578,8 +567,7 @@ fn readStringRaw(allocator: &mem.Allocator, in_stream: var) ![]u8 {...@@ -578,8 +567,7 @@ fn readStringRaw(allocator: &mem.Allocator, in_stream: var) ![]u8 {
578 var buf = ArrayList(u8).init(allocator);567 var buf = ArrayList(u8).init(allocator);
579 while (true) {568 while (true) {
580 const byte = try in_stream.readByte();569 const byte = try in_stream.readByte();
581 if (byte == 0)570 if (byte == 0) break;
582 break;
583 try buf.append(byte);571 try buf.append(byte);
584 }572 }
585 return buf.toSlice();573 return buf.toSlice();
...@@ -600,7 +588,7 @@ fn readAllocBytes(allocator: &mem.Allocator, in_stream: var, size: usize) ![]u8...@@ -600,7 +588,7 @@ fn readAllocBytes(allocator: &mem.Allocator, in_stream: var, size: usize) ![]u8
600588
601fn parseFormValueBlockLen(allocator: &mem.Allocator, in_stream: var, size: usize) !FormValue {589fn parseFormValueBlockLen(allocator: &mem.Allocator, in_stream: var, size: usize) !FormValue {
602 const buf = try readAllocBytes(allocator, in_stream, size);590 const buf = try readAllocBytes(allocator, in_stream, size);
603 return FormValue { .Block = buf };591 return FormValue{ .Block = buf };
604}592}
605593
606fn parseFormValueBlock(allocator: &mem.Allocator, in_stream: var, size: usize) !FormValue {594fn parseFormValueBlock(allocator: &mem.Allocator, in_stream: var, size: usize) !FormValue {
...@@ -609,26 +597,23 @@ fn parseFormValueBlock(allocator: &mem.Allocator, in_stream: var, size: usize) !...@@ -609,26 +597,23 @@ fn parseFormValueBlock(allocator: &mem.Allocator, in_stream: var, size: usize) !
609}597}
610598
611fn parseFormValueConstant(allocator: &mem.Allocator, in_stream: var, signed: bool, size: usize) !FormValue {599fn parseFormValueConstant(allocator: &mem.Allocator, in_stream: var, signed: bool, size: usize) !FormValue {
612 return FormValue { .Const = Constant {600 return FormValue{ .Const = Constant{
613 .signed = signed,601 .signed = signed,
614 .payload = try readAllocBytes(allocator, in_stream, size),602 .payload = try readAllocBytes(allocator, in_stream, size),
615 }};603 } };
616}604}
617605
618fn parseFormValueDwarfOffsetSize(in_stream: var, is_64: bool) !u64 {606fn parseFormValueDwarfOffsetSize(in_stream: var, is_64: bool) !u64 {
619 return if (is_64) try in_stream.readIntLe(u64)607 return if (is_64) try in_stream.readIntLe(u64) else u64(try in_stream.readIntLe(u32));
620 else u64(try in_stream.readIntLe(u32)) ;
621}608}
622609
623fn parseFormValueTargetAddrSize(in_stream: var) !u64 {610fn parseFormValueTargetAddrSize(in_stream: var) !u64 {
624 return if (@sizeOf(usize) == 4) u64(try in_stream.readIntLe(u32))611 return if (@sizeOf(usize) == 4) u64(try in_stream.readIntLe(u32)) else if (@sizeOf(usize) == 8) try in_stream.readIntLe(u64) else unreachable;
625 else if (@sizeOf(usize) == 8) try in_stream.readIntLe(u64)
626 else unreachable;
627}612}
628613
629fn parseFormValueRefLen(allocator: &mem.Allocator, in_stream: var, size: usize) !FormValue {614fn parseFormValueRefLen(allocator: &mem.Allocator, in_stream: var, size: usize) !FormValue {
630 const buf = try readAllocBytes(allocator, in_stream, size);615 const buf = try readAllocBytes(allocator, in_stream, size);
631 return FormValue { .Ref = buf };616 return FormValue{ .Ref = buf };
632}617}
633618
634fn parseFormValueRef(allocator: &mem.Allocator, in_stream: var, comptime T: type) !FormValue {619fn parseFormValueRef(allocator: &mem.Allocator, in_stream: var, comptime T: type) !FormValue {
...@@ -646,11 +631,9 @@ const ParseFormValueError = error {...@@ -646,11 +631,9 @@ const ParseFormValueError = error {
646 OutOfMemory,631 OutOfMemory,
647};632};
648633
649fn parseFormValue(allocator: &mem.Allocator, in_stream: var, form_id: u64, is_64: bool)634fn parseFormValue(allocator: &mem.Allocator, in_stream: var, form_id: u64, is_64: bool) ParseFormValueError!FormValue {
650 ParseFormValueError!FormValue
651{
652 return switch (form_id) {635 return switch (form_id) {
653 DW.FORM_addr => FormValue { .Address = try parseFormValueTargetAddrSize(in_stream) },636 DW.FORM_addr => FormValue{ .Address = try parseFormValueTargetAddrSize(in_stream) },
654 DW.FORM_block1 => parseFormValueBlock(allocator, in_stream, 1),637 DW.FORM_block1 => parseFormValueBlock(allocator, in_stream, 1),
655 DW.FORM_block2 => parseFormValueBlock(allocator, in_stream, 2),638 DW.FORM_block2 => parseFormValueBlock(allocator, in_stream, 2),
656 DW.FORM_block4 => parseFormValueBlock(allocator, in_stream, 4),639 DW.FORM_block4 => parseFormValueBlock(allocator, in_stream, 4),
...@@ -662,7 +645,8 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: var, form_id: u64, is_64...@@ -662,7 +645,8 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: var, form_id: u64, is_64
662 DW.FORM_data2 => parseFormValueConstant(allocator, in_stream, false, 2),645 DW.FORM_data2 => parseFormValueConstant(allocator, in_stream, false, 2),
663 DW.FORM_data4 => parseFormValueConstant(allocator, in_stream, false, 4),646 DW.FORM_data4 => parseFormValueConstant(allocator, in_stream, false, 4),
664 DW.FORM_data8 => parseFormValueConstant(allocator, in_stream, false, 8),647 DW.FORM_data8 => parseFormValueConstant(allocator, in_stream, false, 8),
665 DW.FORM_udata, DW.FORM_sdata => {648 DW.FORM_udata,
649 DW.FORM_sdata => {
666 const block_len = try readULeb128(in_stream);650 const block_len = try readULeb128(in_stream);
667 const signed = form_id == DW.FORM_sdata;651 const signed = form_id == DW.FORM_sdata;
668 return parseFormValueConstant(allocator, in_stream, signed, block_len);652 return parseFormValueConstant(allocator, in_stream, signed, block_len);
...@@ -670,11 +654,11 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: var, form_id: u64, is_64...@@ -670,11 +654,11 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: var, form_id: u64, is_64
670 DW.FORM_exprloc => {654 DW.FORM_exprloc => {
671 const size = try readULeb128(in_stream);655 const size = try readULeb128(in_stream);
672 const buf = try readAllocBytes(allocator, in_stream, size);656 const buf = try readAllocBytes(allocator, in_stream, size);
673 return FormValue { .ExprLoc = buf };657 return FormValue{ .ExprLoc = buf };
674 },658 },
675 DW.FORM_flag => FormValue { .Flag = (try in_stream.readByte()) != 0 },659 DW.FORM_flag => FormValue{ .Flag = (try in_stream.readByte()) != 0 },
676 DW.FORM_flag_present => FormValue { .Flag = true },660 DW.FORM_flag_present => FormValue{ .Flag = true },
677 DW.FORM_sec_offset => FormValue { .SecOffset = try parseFormValueDwarfOffsetSize(in_stream, is_64) },661 DW.FORM_sec_offset => FormValue{ .SecOffset = try parseFormValueDwarfOffsetSize(in_stream, is_64) },
678662
679 DW.FORM_ref1 => parseFormValueRef(allocator, in_stream, u8),663 DW.FORM_ref1 => parseFormValueRef(allocator, in_stream, u8),
680 DW.FORM_ref2 => parseFormValueRef(allocator, in_stream, u16),664 DW.FORM_ref2 => parseFormValueRef(allocator, in_stream, u16),
...@@ -685,11 +669,11 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: var, form_id: u64, is_64...@@ -685,11 +669,11 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: var, form_id: u64, is_64
685 return parseFormValueRefLen(allocator, in_stream, ref_len);669 return parseFormValueRefLen(allocator, in_stream, ref_len);
686 },670 },
687671
688 DW.FORM_ref_addr => FormValue { .RefAddr = try parseFormValueDwarfOffsetSize(in_stream, is_64) },672 DW.FORM_ref_addr => FormValue{ .RefAddr = try parseFormValueDwarfOffsetSize(in_stream, is_64) },
689 DW.FORM_ref_sig8 => FormValue { .RefSig8 = try in_stream.readIntLe(u64) },673 DW.FORM_ref_sig8 => FormValue{ .RefSig8 = try in_stream.readIntLe(u64) },
690674
691 DW.FORM_string => FormValue { .String = try readStringRaw(allocator, in_stream) },675 DW.FORM_string => FormValue{ .String = try readStringRaw(allocator, in_stream) },
692 DW.FORM_strp => FormValue { .StrPtr = try parseFormValueDwarfOffsetSize(in_stream, is_64) },676 DW.FORM_strp => FormValue{ .StrPtr = try parseFormValueDwarfOffsetSize(in_stream, is_64) },
693 DW.FORM_indirect => {677 DW.FORM_indirect => {
694 const child_form_id = try readULeb128(in_stream);678 const child_form_id = try readULeb128(in_stream);
695 return parseFormValue(allocator, in_stream, child_form_id, is_64);679 return parseFormValue(allocator, in_stream, child_form_id, is_64);
...@@ -705,9 +689,8 @@ fn parseAbbrevTable(st: &ElfStackTrace) !AbbrevTable {...@@ -705,9 +689,8 @@ fn parseAbbrevTable(st: &ElfStackTrace) !AbbrevTable {
705 var result = AbbrevTable.init(st.allocator());689 var result = AbbrevTable.init(st.allocator());
706 while (true) {690 while (true) {
707 const abbrev_code = try readULeb128(in_stream);691 const abbrev_code = try readULeb128(in_stream);
708 if (abbrev_code == 0)692 if (abbrev_code == 0) return result;
709 return result;693 try result.append(AbbrevTableEntry{
710 try result.append(AbbrevTableEntry {
711 .abbrev_code = abbrev_code,694 .abbrev_code = abbrev_code,
712 .tag_id = try readULeb128(in_stream),695 .tag_id = try readULeb128(in_stream),
713 .has_children = (try in_stream.readByte()) == DW.CHILDREN_yes,696 .has_children = (try in_stream.readByte()) == DW.CHILDREN_yes,
...@@ -718,9 +701,8 @@ fn parseAbbrevTable(st: &ElfStackTrace) !AbbrevTable {...@@ -718,9 +701,8 @@ fn parseAbbrevTable(st: &ElfStackTrace) !AbbrevTable {
718 while (true) {701 while (true) {
719 const attr_id = try readULeb128(in_stream);702 const attr_id = try readULeb128(in_stream);
720 const form_id = try readULeb128(in_stream);703 const form_id = try readULeb128(in_stream);
721 if (attr_id == 0 and form_id == 0)704 if (attr_id == 0 and form_id == 0) break;
722 break;705 try attrs.append(AbbrevAttr{
723 try attrs.append(AbbrevAttr {
724 .attr_id = attr_id,706 .attr_id = attr_id,
725 .form_id = form_id,707 .form_id = form_id,
726 });708 });
...@@ -737,7 +719,7 @@ fn getAbbrevTable(st: &ElfStackTrace, abbrev_offset: u64) !&const AbbrevTable {...@@ -737,7 +719,7 @@ fn getAbbrevTable(st: &ElfStackTrace, abbrev_offset: u64) !&const AbbrevTable {
737 }719 }
738 }720 }
739 try st.self_exe_file.seekTo(st.debug_abbrev.offset + abbrev_offset);721 try st.self_exe_file.seekTo(st.debug_abbrev.offset + abbrev_offset);
740 try st.abbrev_table_list.append(AbbrevTableHeader {722 try st.abbrev_table_list.append(AbbrevTableHeader{
741 .offset = abbrev_offset,723 .offset = abbrev_offset,
742 .table = try parseAbbrevTable(st),724 .table = try parseAbbrevTable(st),
743 });725 });
...@@ -746,8 +728,7 @@ fn getAbbrevTable(st: &ElfStackTrace, abbrev_offset: u64) !&const AbbrevTable {...@@ -746,8 +728,7 @@ fn getAbbrevTable(st: &ElfStackTrace, abbrev_offset: u64) !&const AbbrevTable {
746728
747fn getAbbrevTableEntry(abbrev_table: &const AbbrevTable, abbrev_code: u64) ?&const AbbrevTableEntry {729fn getAbbrevTableEntry(abbrev_table: &const AbbrevTable, abbrev_code: u64) ?&const AbbrevTableEntry {
748 for (abbrev_table.toSliceConst()) |*table_entry| {730 for (abbrev_table.toSliceConst()) |*table_entry| {
749 if (table_entry.abbrev_code == abbrev_code)731 if (table_entry.abbrev_code == abbrev_code) return table_entry;
750 return table_entry;
751 }732 }
752 return null;733 return null;
753}734}
...@@ -759,14 +740,14 @@ fn parseDie(st: &ElfStackTrace, abbrev_table: &const AbbrevTable, is_64: bool) !...@@ -759,14 +740,14 @@ fn parseDie(st: &ElfStackTrace, abbrev_table: &const AbbrevTable, is_64: bool) !
759 const abbrev_code = try readULeb128(in_stream);740 const abbrev_code = try readULeb128(in_stream);
760 const table_entry = getAbbrevTableEntry(abbrev_table, abbrev_code) ?? return error.InvalidDebugInfo;741 const table_entry = getAbbrevTableEntry(abbrev_table, abbrev_code) ?? return error.InvalidDebugInfo;
761742
762 var result = Die {743 var result = Die{
763 .tag_id = table_entry.tag_id,744 .tag_id = table_entry.tag_id,
764 .has_children = table_entry.has_children,745 .has_children = table_entry.has_children,
765 .attrs = ArrayList(Die.Attr).init(st.allocator()),746 .attrs = ArrayList(Die.Attr).init(st.allocator()),
766 };747 };
767 try result.attrs.resize(table_entry.attrs.len);748 try result.attrs.resize(table_entry.attrs.len);
768 for (table_entry.attrs.toSliceConst()) |attr, i| {749 for (table_entry.attrs.toSliceConst()) |attr, i| {
769 result.attrs.items[i] = Die.Attr {750 result.attrs.items[i] = Die.Attr{
770 .id = attr.attr_id,751 .id = attr.attr_id,
771 .value = try parseFormValue(st.allocator(), in_stream, attr.form_id, is_64),752 .value = try parseFormValue(st.allocator(), in_stream, attr.form_id, is_64),
772 };753 };
...@@ -790,8 +771,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe...@@ -790,8 +771,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
790771
791 var is_64: bool = undefined;772 var is_64: bool = undefined;
792 const unit_length = try readInitialLength(@typeOf(in_stream.readFn).ReturnType.ErrorSet, in_stream, &is_64);773 const unit_length = try readInitialLength(@typeOf(in_stream.readFn).ReturnType.ErrorSet, in_stream, &is_64);
793 if (unit_length == 0)774 if (unit_length == 0) return error.MissingDebugInfo;
794 return error.MissingDebugInfo;
795 const next_offset = unit_length + (if (is_64) usize(12) else usize(4));775 const next_offset = unit_length + (if (is_64) usize(12) else usize(4));
796776
797 if (compile_unit.index != this_index) {777 if (compile_unit.index != this_index) {
...@@ -803,8 +783,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe...@@ -803,8 +783,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
803 // TODO support 3 and 5783 // TODO support 3 and 5
804 if (version != 2 and version != 4) return error.InvalidDebugInfo;784 if (version != 2 and version != 4) return error.InvalidDebugInfo;
805785
806 const prologue_length = if (is_64) try in_stream.readInt(st.elf.endian, u64)786 const prologue_length = if (is_64) try in_stream.readInt(st.elf.endian, u64) else try in_stream.readInt(st.elf.endian, u32);
807 else try in_stream.readInt(st.elf.endian, u32);
808 const prog_start_offset = (try in_file.getPos()) + prologue_length;787 const prog_start_offset = (try in_file.getPos()) + prologue_length;
809788
810 const minimum_instruction_length = try in_stream.readByte();789 const minimum_instruction_length = try in_stream.readByte();
...@@ -819,38 +798,37 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe...@@ -819,38 +798,37 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
819 const line_base = try in_stream.readByteSigned();798 const line_base = try in_stream.readByteSigned();
820799
821 const line_range = try in_stream.readByte();800 const line_range = try in_stream.readByte();
822 if (line_range == 0)801 if (line_range == 0) return error.InvalidDebugInfo;
823 return error.InvalidDebugInfo;
824802
825 const opcode_base = try in_stream.readByte();803 const opcode_base = try in_stream.readByte();
826804
827 const standard_opcode_lengths = try st.allocator().alloc(u8, opcode_base - 1);805 const standard_opcode_lengths = try st.allocator().alloc(u8, opcode_base - 1);
828806
829 {var i: usize = 0; while (i < opcode_base - 1) : (i += 1) {807 {
830 standard_opcode_lengths[i] = try in_stream.readByte();808 var i: usize = 0;
831 }}809 while (i < opcode_base - 1) : (i += 1) {
810 standard_opcode_lengths[i] = try in_stream.readByte();
811 }
812 }
832813
833 var include_directories = ArrayList([]u8).init(st.allocator());814 var include_directories = ArrayList([]u8).init(st.allocator());
834 try include_directories.append(compile_unit_cwd);815 try include_directories.append(compile_unit_cwd);
835 while (true) {816 while (true) {
836 const dir = try st.readString();817 const dir = try st.readString();
837 if (dir.len == 0)818 if (dir.len == 0) break;
838 break;
839 try include_directories.append(dir);819 try include_directories.append(dir);
840 }820 }
841821
842 var file_entries = ArrayList(FileEntry).init(st.allocator());822 var file_entries = ArrayList(FileEntry).init(st.allocator());
843 var prog = LineNumberProgram.init(default_is_stmt, include_directories.toSliceConst(),823 var prog = LineNumberProgram.init(default_is_stmt, include_directories.toSliceConst(), &file_entries, target_address);
844 &file_entries, target_address);
845824
846 while (true) {825 while (true) {
847 const file_name = try st.readString();826 const file_name = try st.readString();
848 if (file_name.len == 0)827 if (file_name.len == 0) break;
849 break;
850 const dir_index = try readULeb128(in_stream);828 const dir_index = try readULeb128(in_stream);
851 const mtime = try readULeb128(in_stream);829 const mtime = try readULeb128(in_stream);
852 const len_bytes = try readULeb128(in_stream);830 const len_bytes = try readULeb128(in_stream);
853 try file_entries.append(FileEntry {831 try file_entries.append(FileEntry{
854 .file_name = file_name,832 .file_name = file_name,
855 .dir_index = dir_index,833 .dir_index = dir_index,
856 .mtime = mtime,834 .mtime = mtime,
...@@ -866,8 +844,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe...@@ -866,8 +844,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
866 var sub_op: u8 = undefined; // TODO move this to the correct scope and fix the compiler crash844 var sub_op: u8 = undefined; // TODO move this to the correct scope and fix the compiler crash
867 if (opcode == DW.LNS_extended_op) {845 if (opcode == DW.LNS_extended_op) {
868 const op_size = try readULeb128(in_stream);846 const op_size = try readULeb128(in_stream);
869 if (op_size < 1)847 if (op_size < 1) return error.InvalidDebugInfo;
870 return error.InvalidDebugInfo;
871 sub_op = try in_stream.readByte();848 sub_op = try in_stream.readByte();
872 switch (sub_op) {849 switch (sub_op) {
873 DW.LNE_end_sequence => {850 DW.LNE_end_sequence => {
...@@ -884,7 +861,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe...@@ -884,7 +861,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
884 const dir_index = try readULeb128(in_stream);861 const dir_index = try readULeb128(in_stream);
885 const mtime = try readULeb128(in_stream);862 const mtime = try readULeb128(in_stream);
886 const len_bytes = try readULeb128(in_stream);863 const len_bytes = try readULeb128(in_stream);
887 try file_entries.append(FileEntry {864 try file_entries.append(FileEntry{
888 .file_name = file_name,865 .file_name = file_name,
889 .dir_index = dir_index,866 .dir_index = dir_index,
890 .mtime = mtime,867 .mtime = mtime,
...@@ -941,11 +918,9 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe...@@ -941,11 +918,9 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
941 const arg = try in_stream.readInt(st.elf.endian, u16);918 const arg = try in_stream.readInt(st.elf.endian, u16);
942 prog.address += arg;919 prog.address += arg;
943 },920 },
944 DW.LNS_set_prologue_end => {921 DW.LNS_set_prologue_end => {},
945 },
946 else => {922 else => {
947 if (opcode - 1 >= standard_opcode_lengths.len)923 if (opcode - 1 >= standard_opcode_lengths.len) return error.InvalidDebugInfo;
948 return error.InvalidDebugInfo;
949 const len_bytes = standard_opcode_lengths[opcode - 1];924 const len_bytes = standard_opcode_lengths[opcode - 1];
950 try in_file.seekForward(len_bytes);925 try in_file.seekForward(len_bytes);
951 },926 },
...@@ -972,16 +947,13 @@ fn scanAllCompileUnits(st: &ElfStackTrace) !void {...@@ -972,16 +947,13 @@ fn scanAllCompileUnits(st: &ElfStackTrace) !void {
972947
973 var is_64: bool = undefined;948 var is_64: bool = undefined;
974 const unit_length = try readInitialLength(@typeOf(in_stream.readFn).ReturnType.ErrorSet, in_stream, &is_64);949 const unit_length = try readInitialLength(@typeOf(in_stream.readFn).ReturnType.ErrorSet, in_stream, &is_64);
975 if (unit_length == 0)950 if (unit_length == 0) return;
976 return;
977 const next_offset = unit_length + (if (is_64) usize(12) else usize(4));951 const next_offset = unit_length + (if (is_64) usize(12) else usize(4));
978952
979 const version = try in_stream.readInt(st.elf.endian, u16);953 const version = try in_stream.readInt(st.elf.endian, u16);
980 if (version < 2 or version > 5) return error.InvalidDebugInfo;954 if (version < 2 or version > 5) return error.InvalidDebugInfo;
981955
982 const debug_abbrev_offset =956 const debug_abbrev_offset = if (is_64) try in_stream.readInt(st.elf.endian, u64) else try in_stream.readInt(st.elf.endian, u32);
983 if (is_64) try in_stream.readInt(st.elf.endian, u64)
984 else try in_stream.readInt(st.elf.endian, u32);
985957
986 const address_size = try in_stream.readByte();958 const address_size = try in_stream.readByte();
987 if (address_size != @sizeOf(usize)) return error.InvalidDebugInfo;959 if (address_size != @sizeOf(usize)) return error.InvalidDebugInfo;
...@@ -992,15 +964,14 @@ fn scanAllCompileUnits(st: &ElfStackTrace) !void {...@@ -992,15 +964,14 @@ fn scanAllCompileUnits(st: &ElfStackTrace) !void {
992 try st.self_exe_file.seekTo(compile_unit_pos);964 try st.self_exe_file.seekTo(compile_unit_pos);
993965
994 const compile_unit_die = try st.allocator().create(Die);966 const compile_unit_die = try st.allocator().create(Die);
995 *compile_unit_die = try parseDie(st, abbrev_table, is_64);967 compile_unit_die.* = try parseDie(st, abbrev_table, is_64);
996968
997 if (compile_unit_die.tag_id != DW.TAG_compile_unit)969 if (compile_unit_die.tag_id != DW.TAG_compile_unit) return error.InvalidDebugInfo;
998 return error.InvalidDebugInfo;
999970
1000 const pc_range = x: {971 const pc_range = x: {
1001 if (compile_unit_die.getAttrAddr(DW.AT_low_pc)) |low_pc| {972 if (compile_unit_die.getAttrAddr(DW.AT_low_pc)) |low_pc| {
1002 if (compile_unit_die.getAttr(DW.AT_high_pc)) |high_pc_value| {973 if (compile_unit_die.getAttr(DW.AT_high_pc)) |high_pc_value| {
1003 const pc_end = switch (*high_pc_value) {974 const pc_end = switch (high_pc_value.*) {
1004 FormValue.Address => |value| value,975 FormValue.Address => |value| value,
1005 FormValue.Const => |value| b: {976 FormValue.Const => |value| b: {
1006 const offset = try value.asUnsignedLe();977 const offset = try value.asUnsignedLe();
...@@ -1008,7 +979,7 @@ fn scanAllCompileUnits(st: &ElfStackTrace) !void {...@@ -1008,7 +979,7 @@ fn scanAllCompileUnits(st: &ElfStackTrace) !void {
1008 },979 },
1009 else => return error.InvalidDebugInfo,980 else => return error.InvalidDebugInfo,
1010 };981 };
1011 break :x PcRange {982 break :x PcRange{
1012 .start = low_pc,983 .start = low_pc,
1013 .end = pc_end,984 .end = pc_end,
1014 };985 };
...@@ -1016,13 +987,12 @@ fn scanAllCompileUnits(st: &ElfStackTrace) !void {...@@ -1016,13 +987,12 @@ fn scanAllCompileUnits(st: &ElfStackTrace) !void {
1016 break :x null;987 break :x null;
1017 }988 }
1018 } else |err| {989 } else |err| {
1019 if (err != error.MissingDebugInfo)990 if (err != error.MissingDebugInfo) return err;
1020 return err;
1021 break :x null;991 break :x null;
1022 }992 }
1023 };993 };
1024994
1025 try st.compile_unit_list.append(CompileUnit {995 try st.compile_unit_list.append(CompileUnit{
1026 .version = version,996 .version = version,
1027 .is_64 = is_64,997 .is_64 = is_64,
1028 .pc_range = pc_range,998 .pc_range = pc_range,
...@@ -1040,8 +1010,7 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) !&const CompileUnit...@@ -1040,8 +1010,7 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) !&const CompileUnit
1040 const in_stream = &in_file_stream.stream;1010 const in_stream = &in_file_stream.stream;
1041 for (st.compile_unit_list.toSlice()) |*compile_unit| {1011 for (st.compile_unit_list.toSlice()) |*compile_unit| {
1042 if (compile_unit.pc_range) |range| {1012 if (compile_unit.pc_range) |range| {
1043 if (target_address >= range.start and target_address < range.end)1013 if (target_address >= range.start and target_address < range.end) return compile_unit;
1044 return compile_unit;
1045 }1014 }
1046 if (compile_unit.die.getAttrSecOffset(DW.AT_ranges)) |ranges_offset| {1015 if (compile_unit.die.getAttrSecOffset(DW.AT_ranges)) |ranges_offset| {
1047 var base_address: usize = 0;1016 var base_address: usize = 0;
...@@ -1063,8 +1032,7 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) !&const CompileUnit...@@ -1063,8 +1032,7 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) !&const CompileUnit
1063 }1032 }
1064 }1033 }
1065 } else |err| {1034 } else |err| {
1066 if (err != error.MissingDebugInfo)1035 if (err != error.MissingDebugInfo) return err;
1067 return err;
1068 continue;1036 continue;
1069 }1037 }
1070 }1038 }
...@@ -1073,8 +1041,8 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) !&const CompileUnit...@@ -1073,8 +1041,8 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) !&const CompileUnit
10731041
1074fn readInitialLength(comptime E: type, in_stream: &io.InStream(E), is_64: &bool) !u64 {1042fn readInitialLength(comptime E: type, in_stream: &io.InStream(E), is_64: &bool) !u64 {
1075 const first_32_bits = try in_stream.readIntLe(u32);1043 const first_32_bits = try in_stream.readIntLe(u32);
1076 *is_64 = (first_32_bits == 0xffffffff);1044 is_64.* = (first_32_bits == 0xffffffff);
1077 if (*is_64) {1045 if (is_64.*) {
1078 return in_stream.readIntLe(u64);1046 return in_stream.readIntLe(u64);
1079 } else {1047 } else {
1080 if (first_32_bits >= 0xfffffff0) return error.InvalidDebugInfo;1048 if (first_32_bits >= 0xfffffff0) return error.InvalidDebugInfo;
...@@ -1091,13 +1059,11 @@ fn readULeb128(in_stream: var) !u64 {...@@ -1091,13 +1059,11 @@ fn readULeb128(in_stream: var) !u64 {
10911059
1092 var operand: u64 = undefined;1060 var operand: u64 = undefined;
10931061
1094 if (@shlWithOverflow(u64, byte & 0b01111111, u6(shift), &operand))1062 if (@shlWithOverflow(u64, byte & 0b01111111, u6(shift), &operand)) return error.InvalidDebugInfo;
1095 return error.InvalidDebugInfo;
10961063
1097 result |= operand;1064 result |= operand;
10981065
1099 if ((byte & 0b10000000) == 0)1066 if ((byte & 0b10000000) == 0) return result;
1100 return result;
11011067
1102 shift += 7;1068 shift += 7;
1103 }1069 }
...@@ -1112,15 +1078,13 @@ fn readILeb128(in_stream: var) !i64 {...@@ -1112,15 +1078,13 @@ fn readILeb128(in_stream: var) !i64 {
11121078
1113 var operand: i64 = undefined;1079 var operand: i64 = undefined;
11141080
1115 if (@shlWithOverflow(i64, byte & 0b01111111, u6(shift), &operand))1081 if (@shlWithOverflow(i64, byte & 0b01111111, u6(shift), &operand)) return error.InvalidDebugInfo;
1116 return error.InvalidDebugInfo;
11171082
1118 result |= operand;1083 result |= operand;
1119 shift += 7;1084 shift += 7;
11201085
1121 if ((byte & 0b10000000) == 0) {1086 if ((byte & 0b10000000) == 0) {
1122 if (shift < @sizeOf(i64) * 8 and (byte & 0b01000000) != 0)1087 if (shift < @sizeOf(i64) * 8 and (byte & 0b01000000) != 0) result |= -(i64(1) << u6(shift));
1123 result |= -(i64(1) << u6(shift));
1124 return result;1088 return result;
1125 }1089 }
1126 }1090 }
...@@ -1131,7 +1095,6 @@ pub const global_allocator = &global_fixed_allocator.allocator;...@@ -1131,7 +1095,6 @@ pub const global_allocator = &global_fixed_allocator.allocator;
1131var global_fixed_allocator = std.heap.FixedBufferAllocator.init(global_allocator_mem[0..]);1095var global_fixed_allocator = std.heap.FixedBufferAllocator.init(global_allocator_mem[0..]);
1132var global_allocator_mem: [100 * 1024]u8 = undefined;1096var global_allocator_mem: [100 * 1024]u8 = undefined;
11331097
1134
1135// TODO make thread safe1098// TODO make thread safe
1136var debug_info_allocator: ?&mem.Allocator = null;1099var debug_info_allocator: ?&mem.Allocator = null;
1137var debug_info_direct_allocator: std.heap.DirectAllocator = undefined;1100var debug_info_direct_allocator: std.heap.DirectAllocator = undefined;
std/math/index.zig+29-46
...@@ -47,12 +47,12 @@ pub fn forceEval(value: var) void {...@@ -47,12 +47,12 @@ pub fn forceEval(value: var) void {
47 f32 => {47 f32 => {
48 var x: f32 = undefined;48 var x: f32 = undefined;
49 const p = @ptrCast(&volatile f32, &x);49 const p = @ptrCast(&volatile f32, &x);
50 *p = x;50 p.* = x;
51 },51 },
52 f64 => {52 f64 => {
53 var x: f64 = undefined;53 var x: f64 = undefined;
54 const p = @ptrCast(&volatile f64, &x);54 const p = @ptrCast(&volatile f64, &x);
55 *p = x;55 p.* = x;
56 },56 },
57 else => {57 else => {
58 @compileError("forceEval not implemented for " ++ @typeName(T));58 @compileError("forceEval not implemented for " ++ @typeName(T));
...@@ -179,7 +179,6 @@ test "math" {...@@ -179,7 +179,6 @@ test "math" {
179 _ = @import("complex/index.zig");179 _ = @import("complex/index.zig");
180}180}
181181
182
183pub fn min(x: var, y: var) @typeOf(x + y) {182pub fn min(x: var, y: var) @typeOf(x + y) {
184 return if (x < y) x else y;183 return if (x < y) x else y;
185}184}
...@@ -280,10 +279,10 @@ pub fn rotr(comptime T: type, x: T, r: var) T {...@@ -280,10 +279,10 @@ pub fn rotr(comptime T: type, x: T, r: var) T {
280}279}
281280
282test "math.rotr" {281test "math.rotr" {
283 assert(rotr(u8, 0b00000001, usize(0)) == 0b00000001);282 assert(rotr(u8, 0b00000001, usize(0)) == 0b00000001);
284 assert(rotr(u8, 0b00000001, usize(9)) == 0b10000000);283 assert(rotr(u8, 0b00000001, usize(9)) == 0b10000000);
285 assert(rotr(u8, 0b00000001, usize(8)) == 0b00000001);284 assert(rotr(u8, 0b00000001, usize(8)) == 0b00000001);
286 assert(rotr(u8, 0b00000001, usize(4)) == 0b00010000);285 assert(rotr(u8, 0b00000001, usize(4)) == 0b00010000);
287 assert(rotr(u8, 0b00000001, isize(-1)) == 0b00000010);286 assert(rotr(u8, 0b00000001, isize(-1)) == 0b00000010);
288}287}
289288
...@@ -299,14 +298,13 @@ pub fn rotl(comptime T: type, x: T, r: var) T {...@@ -299,14 +298,13 @@ pub fn rotl(comptime T: type, x: T, r: var) T {
299}298}
300299
301test "math.rotl" {300test "math.rotl" {
302 assert(rotl(u8, 0b00000001, usize(0)) == 0b00000001);301 assert(rotl(u8, 0b00000001, usize(0)) == 0b00000001);
303 assert(rotl(u8, 0b00000001, usize(9)) == 0b00000010);302 assert(rotl(u8, 0b00000001, usize(9)) == 0b00000010);
304 assert(rotl(u8, 0b00000001, usize(8)) == 0b00000001);303 assert(rotl(u8, 0b00000001, usize(8)) == 0b00000001);
305 assert(rotl(u8, 0b00000001, usize(4)) == 0b00010000);304 assert(rotl(u8, 0b00000001, usize(4)) == 0b00010000);
306 assert(rotl(u8, 0b00000001, isize(-1)) == 0b10000000);305 assert(rotl(u8, 0b00000001, isize(-1)) == 0b10000000);
307}306}
308307
309
310pub fn Log2Int(comptime T: type) type {308pub fn Log2Int(comptime T: type) type {
311 return @IntType(false, log2(T.bit_count));309 return @IntType(false, log2(T.bit_count));
312}310}
...@@ -323,14 +321,14 @@ fn testOverflow() void {...@@ -323,14 +321,14 @@ fn testOverflow() void {
323 assert((shlExact(i32, 0b11, 4) catch unreachable) == 0b110000);321 assert((shlExact(i32, 0b11, 4) catch unreachable) == 0b110000);
324}322}
325323
326
327pub fn absInt(x: var) !@typeOf(x) {324pub fn absInt(x: var) !@typeOf(x) {
328 const T = @typeOf(x);325 const T = @typeOf(x);
329 comptime assert(@typeId(T) == builtin.TypeId.Int); // must pass an integer to absInt326 comptime assert(@typeId(T) == builtin.TypeId.Int); // must pass an integer to absInt
330 comptime assert(T.is_signed); // must pass a signed integer to absInt327 comptime assert(T.is_signed); // must pass a signed integer to absInt
331 if (x == @minValue(@typeOf(x)))328
329 if (x == @minValue(@typeOf(x))) {
332 return error.Overflow;330 return error.Overflow;
333 {331 } else {
334 @setRuntimeSafety(false);332 @setRuntimeSafety(false);
335 return if (x < 0) -x else x;333 return if (x < 0) -x else x;
336 }334 }
...@@ -349,10 +347,8 @@ pub const absFloat = @import("fabs.zig").fabs;...@@ -349,10 +347,8 @@ pub const absFloat = @import("fabs.zig").fabs;
349347
350pub fn divTrunc(comptime T: type, numerator: T, denominator: T) !T {348pub fn divTrunc(comptime T: type, numerator: T, denominator: T) !T {
351 @setRuntimeSafety(false);349 @setRuntimeSafety(false);
352 if (denominator == 0)350 if (denominator == 0) return error.DivisionByZero;
353 return error.DivisionByZero;351 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1) return error.Overflow;
354 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)
355 return error.Overflow;
356 return @divTrunc(numerator, denominator);352 return @divTrunc(numerator, denominator);
357}353}
358354
...@@ -372,10 +368,8 @@ fn testDivTrunc() void {...@@ -372,10 +368,8 @@ fn testDivTrunc() void {
372368
373pub fn divFloor(comptime T: type, numerator: T, denominator: T) !T {369pub fn divFloor(comptime T: type, numerator: T, denominator: T) !T {
374 @setRuntimeSafety(false);370 @setRuntimeSafety(false);
375 if (denominator == 0)371 if (denominator == 0) return error.DivisionByZero;
376 return error.DivisionByZero;372 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1) return error.Overflow;
377 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)
378 return error.Overflow;
379 return @divFloor(numerator, denominator);373 return @divFloor(numerator, denominator);
380}374}
381375
...@@ -395,13 +389,10 @@ fn testDivFloor() void {...@@ -395,13 +389,10 @@ fn testDivFloor() void {
395389
396pub fn divExact(comptime T: type, numerator: T, denominator: T) !T {390pub fn divExact(comptime T: type, numerator: T, denominator: T) !T {
397 @setRuntimeSafety(false);391 @setRuntimeSafety(false);
398 if (denominator == 0)392 if (denominator == 0) return error.DivisionByZero;
399 return error.DivisionByZero;393 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1) return error.Overflow;
400 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)
401 return error.Overflow;
402 const result = @divTrunc(numerator, denominator);394 const result = @divTrunc(numerator, denominator);
403 if (result * denominator != numerator)395 if (result * denominator != numerator) return error.UnexpectedRemainder;
404 return error.UnexpectedRemainder;
405 return result;396 return result;
406}397}
407398
...@@ -423,10 +414,8 @@ fn testDivExact() void {...@@ -423,10 +414,8 @@ fn testDivExact() void {
423414
424pub fn mod(comptime T: type, numerator: T, denominator: T) !T {415pub fn mod(comptime T: type, numerator: T, denominator: T) !T {
425 @setRuntimeSafety(false);416 @setRuntimeSafety(false);
426 if (denominator == 0)417 if (denominator == 0) return error.DivisionByZero;
427 return error.DivisionByZero;418 if (denominator < 0) return error.NegativeDenominator;
428 if (denominator < 0)
429 return error.NegativeDenominator;
430 return @mod(numerator, denominator);419 return @mod(numerator, denominator);
431}420}
432421
...@@ -448,10 +437,8 @@ fn testMod() void {...@@ -448,10 +437,8 @@ fn testMod() void {
448437
449pub fn rem(comptime T: type, numerator: T, denominator: T) !T {438pub fn rem(comptime T: type, numerator: T, denominator: T) !T {
450 @setRuntimeSafety(false);439 @setRuntimeSafety(false);
451 if (denominator == 0)440 if (denominator == 0) return error.DivisionByZero;
452 return error.DivisionByZero;441 if (denominator < 0) return error.NegativeDenominator;
453 if (denominator < 0)
454 return error.NegativeDenominator;
455 return @rem(numerator, denominator);442 return @rem(numerator, denominator);
456}443}
457444
...@@ -475,8 +462,7 @@ fn testRem() void {...@@ -475,8 +462,7 @@ fn testRem() void {
475/// Result is an unsigned integer.462/// Result is an unsigned integer.
476pub fn absCast(x: var) @IntType(false, @typeOf(x).bit_count) {463pub fn absCast(x: var) @IntType(false, @typeOf(x).bit_count) {
477 const uint = @IntType(false, @typeOf(x).bit_count);464 const uint = @IntType(false, @typeOf(x).bit_count);
478 if (x >= 0)465 if (x >= 0) return uint(x);
479 return uint(x);
480466
481 return uint(-(x + 1)) + 1;467 return uint(-(x + 1)) + 1;
482}468}
...@@ -495,15 +481,12 @@ test "math.absCast" {...@@ -495,15 +481,12 @@ test "math.absCast" {
495/// Returns the negation of the integer parameter.481/// Returns the negation of the integer parameter.
496/// Result is a signed integer.482/// Result is a signed integer.
497pub fn negateCast(x: var) !@IntType(true, @typeOf(x).bit_count) {483pub fn negateCast(x: var) !@IntType(true, @typeOf(x).bit_count) {
498 if (@typeOf(x).is_signed)484 if (@typeOf(x).is_signed) return negate(x);
499 return negate(x);
500485
501 const int = @IntType(true, @typeOf(x).bit_count);486 const int = @IntType(true, @typeOf(x).bit_count);
502 if (x > -@minValue(int))487 if (x > -@minValue(int)) return error.Overflow;
503 return error.Overflow;
504488
505 if (x == -@minValue(int))489 if (x == -@minValue(int)) return @minValue(int);
506 return @minValue(int);
507490
508 return -int(x);491 return -int(x);
509}492}
...@@ -546,7 +529,7 @@ pub fn floorPowerOfTwo(comptime T: type, value: T) T {...@@ -546,7 +529,7 @@ pub fn floorPowerOfTwo(comptime T: type, value: T) T {
546 var x = value;529 var x = value;
547530
548 comptime var i = 1;531 comptime var i = 1;
549 inline while(T.bit_count > i) : (i *= 2) {532 inline while (T.bit_count > i) : (i *= 2) {
550 x |= (x >> i);533 x |= (x >> i);
551 }534 }
552535
std/mem.zig+124-73
...@@ -6,14 +6,14 @@ const builtin = @import("builtin");...@@ -6,14 +6,14 @@ const builtin = @import("builtin");
6const mem = this;6const mem = this;
77
8pub const Allocator = struct {8pub const Allocator = struct {
9 const Error = error {OutOfMemory};9 const Error = error{OutOfMemory};
1010
11 /// Allocate byte_count bytes and return them in a slice, with the11 /// Allocate byte_count bytes and return them in a slice, with the
12 /// slice's pointer aligned at least to alignment bytes.12 /// slice's pointer aligned at least to alignment bytes.
13 /// The returned newly allocated memory is undefined.13 /// The returned newly allocated memory is undefined.
14 /// `alignment` is guaranteed to be >= 114 /// `alignment` is guaranteed to be >= 1
15 /// `alignment` is guaranteed to be a power of 215 /// `alignment` is guaranteed to be a power of 2
16 allocFn: fn (self: &Allocator, byte_count: usize, alignment: u29) Error![]u8,16 allocFn: fn(self: &Allocator, byte_count: usize, alignment: u29) Error![]u8,
1717
18 /// If `new_byte_count > old_mem.len`:18 /// If `new_byte_count > old_mem.len`:
19 /// * `old_mem.len` is the same as what was returned from allocFn or reallocFn.19 /// * `old_mem.len` is the same as what was returned from allocFn or reallocFn.
...@@ -26,10 +26,10 @@ pub const Allocator = struct {...@@ -26,10 +26,10 @@ pub const Allocator = struct {
26 /// The returned newly allocated memory is undefined.26 /// The returned newly allocated memory is undefined.
27 /// `alignment` is guaranteed to be >= 127 /// `alignment` is guaranteed to be >= 1
28 /// `alignment` is guaranteed to be a power of 228 /// `alignment` is guaranteed to be a power of 2
29 reallocFn: fn (self: &Allocator, old_mem: []u8, new_byte_count: usize, alignment: u29) Error![]u8,29 reallocFn: fn(self: &Allocator, old_mem: []u8, new_byte_count: usize, alignment: u29) Error![]u8,
3030
31 /// Guaranteed: `old_mem.len` is the same as what was returned from `allocFn` or `reallocFn`31 /// Guaranteed: `old_mem.len` is the same as what was returned from `allocFn` or `reallocFn`
32 freeFn: fn (self: &Allocator, old_mem: []u8) void,32 freeFn: fn(self: &Allocator, old_mem: []u8) void,
3333
34 fn create(self: &Allocator, comptime T: type) !&T {34 fn create(self: &Allocator, comptime T: type) !&T {
35 if (@sizeOf(T) == 0) return &{};35 if (@sizeOf(T) == 0) return &{};
...@@ -47,7 +47,7 @@ pub const Allocator = struct {...@@ -47,7 +47,7 @@ pub const Allocator = struct {
47 if (@sizeOf(T) == 0) return &{};47 if (@sizeOf(T) == 0) return &{};
48 const slice = try self.alloc(T, 1);48 const slice = try self.alloc(T, 1);
49 const ptr = &slice[0];49 const ptr = &slice[0];
50 *ptr = *init;50 ptr.* = init.*;
51 return ptr;51 return ptr;
52 }52 }
5353
...@@ -59,9 +59,7 @@ pub const Allocator = struct {...@@ -59,9 +59,7 @@ pub const Allocator = struct {
59 return self.alignedAlloc(T, @alignOf(T), n);59 return self.alignedAlloc(T, @alignOf(T), n);
60 }60 }
6161
62 fn alignedAlloc(self: &Allocator, comptime T: type, comptime alignment: u29,62 fn alignedAlloc(self: &Allocator, comptime T: type, comptime alignment: u29, n: usize) ![]align(alignment) T {
63 n: usize) ![]align(alignment) T
64 {
65 if (n == 0) {63 if (n == 0) {
66 return (&align(alignment) T)(undefined)[0..0];64 return (&align(alignment) T)(undefined)[0..0];
67 }65 }
...@@ -70,7 +68,7 @@ pub const Allocator = struct {...@@ -70,7 +68,7 @@ pub const Allocator = struct {
70 assert(byte_slice.len == byte_count);68 assert(byte_slice.len == byte_count);
71 // This loop gets optimized out in ReleaseFast mode69 // This loop gets optimized out in ReleaseFast mode
72 for (byte_slice) |*byte| {70 for (byte_slice) |*byte| {
73 *byte = undefined;71 byte.* = undefined;
74 }72 }
75 return ([]align(alignment) T)(@alignCast(alignment, byte_slice));73 return ([]align(alignment) T)(@alignCast(alignment, byte_slice));
76 }74 }
...@@ -79,9 +77,7 @@ pub const Allocator = struct {...@@ -79,9 +77,7 @@ pub const Allocator = struct {
79 return self.alignedRealloc(T, @alignOf(T), @alignCast(@alignOf(T), old_mem), n);77 return self.alignedRealloc(T, @alignOf(T), @alignCast(@alignOf(T), old_mem), n);
80 }78 }
8179
82 fn alignedRealloc(self: &Allocator, comptime T: type, comptime alignment: u29,80 fn alignedRealloc(self: &Allocator, comptime T: type, comptime alignment: u29, old_mem: []align(alignment) T, n: usize) ![]align(alignment) T {
83 old_mem: []align(alignment) T, n: usize) ![]align(alignment) T
84 {
85 if (old_mem.len == 0) {81 if (old_mem.len == 0) {
86 return self.alloc(T, n);82 return self.alloc(T, n);
87 }83 }
...@@ -97,7 +93,7 @@ pub const Allocator = struct {...@@ -97,7 +93,7 @@ pub const Allocator = struct {
97 if (n > old_mem.len) {93 if (n > old_mem.len) {
98 // This loop gets optimized out in ReleaseFast mode94 // This loop gets optimized out in ReleaseFast mode
99 for (byte_slice[old_byte_slice.len..]) |*byte| {95 for (byte_slice[old_byte_slice.len..]) |*byte| {
100 *byte = undefined;96 byte.* = undefined;
101 }97 }
102 }98 }
103 return ([]T)(@alignCast(alignment, byte_slice));99 return ([]T)(@alignCast(alignment, byte_slice));
...@@ -110,9 +106,7 @@ pub const Allocator = struct {...@@ -110,9 +106,7 @@ pub const Allocator = struct {
110 return self.alignedShrink(T, @alignOf(T), @alignCast(@alignOf(T), old_mem), n);106 return self.alignedShrink(T, @alignOf(T), @alignCast(@alignOf(T), old_mem), n);
111 }107 }
112108
113 fn alignedShrink(self: &Allocator, comptime T: type, comptime alignment: u29,109 fn alignedShrink(self: &Allocator, comptime T: type, comptime alignment: u29, old_mem: []align(alignment) T, n: usize) []align(alignment) T {
114 old_mem: []align(alignment) T, n: usize) []align(alignment) T
115 {
116 if (n == 0) {110 if (n == 0) {
117 self.free(old_mem);111 self.free(old_mem);
118 return old_mem[0..0];112 return old_mem[0..0];
...@@ -131,8 +125,7 @@ pub const Allocator = struct {...@@ -131,8 +125,7 @@ pub const Allocator = struct {
131125
132 fn free(self: &Allocator, memory: var) void {126 fn free(self: &Allocator, memory: var) void {
133 const bytes = ([]const u8)(memory);127 const bytes = ([]const u8)(memory);
134 if (bytes.len == 0)128 if (bytes.len == 0) return;
135 return;
136 const non_const_ptr = @intToPtr(&u8, @ptrToInt(bytes.ptr));129 const non_const_ptr = @intToPtr(&u8, @ptrToInt(bytes.ptr));
137 self.freeFn(self, non_const_ptr[0..bytes.len]);130 self.freeFn(self, non_const_ptr[0..bytes.len]);
138 }131 }
...@@ -146,11 +139,13 @@ pub fn copy(comptime T: type, dest: []T, source: []const T) void {...@@ -146,11 +139,13 @@ pub fn copy(comptime T: type, dest: []T, source: []const T) void {
146 // this and automatically omit safety checks for loops139 // this and automatically omit safety checks for loops
147 @setRuntimeSafety(false);140 @setRuntimeSafety(false);
148 assert(dest.len >= source.len);141 assert(dest.len >= source.len);
149 for (source) |s, i| dest[i] = s;142 for (source) |s, i|
143 dest[i] = s;
150}144}
151145
152pub fn set(comptime T: type, dest: []T, value: T) void {146pub fn set(comptime T: type, dest: []T, value: T) void {
153 for (dest) |*d| *d = value;147 for (dest) |*d|
148 d.* = value;
154}149}
155150
156/// Returns true if lhs < rhs, false otherwise151/// Returns true if lhs < rhs, false otherwise
...@@ -229,8 +224,7 @@ pub fn lastIndexOfScalar(comptime T: type, slice: []const T, value: T) ?usize {...@@ -229,8 +224,7 @@ pub fn lastIndexOfScalar(comptime T: type, slice: []const T, value: T) ?usize {
229 var i: usize = slice.len;224 var i: usize = slice.len;
230 while (i != 0) {225 while (i != 0) {
231 i -= 1;226 i -= 1;
232 if (slice[i] == value)227 if (slice[i] == value) return i;
233 return i;
234 }228 }
235 return null;229 return null;
236}230}
...@@ -238,8 +232,7 @@ pub fn lastIndexOfScalar(comptime T: type, slice: []const T, value: T) ?usize {...@@ -238,8 +232,7 @@ pub fn lastIndexOfScalar(comptime T: type, slice: []const T, value: T) ?usize {
238pub fn indexOfScalarPos(comptime T: type, slice: []const T, start_index: usize, value: T) ?usize {232pub fn indexOfScalarPos(comptime T: type, slice: []const T, start_index: usize, value: T) ?usize {
239 var i: usize = start_index;233 var i: usize = start_index;
240 while (i < slice.len) : (i += 1) {234 while (i < slice.len) : (i += 1) {
241 if (slice[i] == value)235 if (slice[i] == value) return i;
242 return i;
243 }236 }
244 return null;237 return null;
245}238}
...@@ -253,8 +246,7 @@ pub fn lastIndexOfAny(comptime T: type, slice: []const T, values: []const T) ?us...@@ -253,8 +246,7 @@ pub fn lastIndexOfAny(comptime T: type, slice: []const T, values: []const T) ?us
253 while (i != 0) {246 while (i != 0) {
254 i -= 1;247 i -= 1;
255 for (values) |value| {248 for (values) |value| {
256 if (slice[i] == value)249 if (slice[i] == value) return i;
257 return i;
258 }250 }
259 }251 }
260 return null;252 return null;
...@@ -264,8 +256,7 @@ pub fn indexOfAnyPos(comptime T: type, slice: []const T, start_index: usize, val...@@ -264,8 +256,7 @@ pub fn indexOfAnyPos(comptime T: type, slice: []const T, start_index: usize, val
264 var i: usize = start_index;256 var i: usize = start_index;
265 while (i < slice.len) : (i += 1) {257 while (i < slice.len) : (i += 1) {
266 for (values) |value| {258 for (values) |value| {
267 if (slice[i] == value)259 if (slice[i] == value) return i;
268 return i;
269 }260 }
270 }261 }
271 return null;262 return null;
...@@ -279,28 +270,23 @@ pub fn indexOf(comptime T: type, haystack: []const T, needle: []const T) ?usize...@@ -279,28 +270,23 @@ pub fn indexOf(comptime T: type, haystack: []const T, needle: []const T) ?usize
279/// To start looking at a different index, slice the haystack first.270/// To start looking at a different index, slice the haystack first.
280/// TODO is there even a better algorithm for this?271/// TODO is there even a better algorithm for this?
281pub fn lastIndexOf(comptime T: type, haystack: []const T, needle: []const T) ?usize {272pub fn lastIndexOf(comptime T: type, haystack: []const T, needle: []const T) ?usize {
282 if (needle.len > haystack.len)273 if (needle.len > haystack.len) return null;
283 return null;
284274
285 var i: usize = haystack.len - needle.len;275 var i: usize = haystack.len - needle.len;
286 while (true) : (i -= 1) {276 while (true) : (i -= 1) {
287 if (mem.eql(T, haystack[i..i+needle.len], needle))277 if (mem.eql(T, haystack[i..i + needle.len], needle)) return i;
288 return i;278 if (i == 0) return null;
289 if (i == 0)
290 return null;
291 }279 }
292}280}
293281
294// TODO boyer-moore algorithm282// TODO boyer-moore algorithm
295pub fn indexOfPos(comptime T: type, haystack: []const T, start_index: usize, needle: []const T) ?usize {283pub fn indexOfPos(comptime T: type, haystack: []const T, start_index: usize, needle: []const T) ?usize {
296 if (needle.len > haystack.len)284 if (needle.len > haystack.len) return null;
297 return null;
298285
299 var i: usize = start_index;286 var i: usize = start_index;
300 const end = haystack.len - needle.len;287 const end = haystack.len - needle.len;
301 while (i <= end) : (i += 1) {288 while (i <= end) : (i += 1) {
302 if (eql(T, haystack[i .. i + needle.len], needle))289 if (eql(T, haystack[i..i + needle.len], needle)) return i;
303 return i;
304 }290 }
305 return null;291 return null;
306}292}
...@@ -355,9 +341,12 @@ pub fn readIntBE(comptime T: type, bytes: []const u8) T {...@@ -355,9 +341,12 @@ pub fn readIntBE(comptime T: type, bytes: []const u8) T {
355 }341 }
356 assert(bytes.len == @sizeOf(T));342 assert(bytes.len == @sizeOf(T));
357 var result: T = 0;343 var result: T = 0;
358 {comptime var i = 0; inline while (i < @sizeOf(T)) : (i += 1) {344 {
359 result = (result << 8) | T(bytes[i]);345 comptime var i = 0;
360 }}346 inline while (i < @sizeOf(T)) : (i += 1) {
347 result = (result << 8) | T(bytes[i]);
348 }
349 }
361 return result;350 return result;
362}351}
363352
...@@ -369,9 +358,12 @@ pub fn readIntLE(comptime T: type, bytes: []const u8) T {...@@ -369,9 +358,12 @@ pub fn readIntLE(comptime T: type, bytes: []const u8) T {
369 }358 }
370 assert(bytes.len == @sizeOf(T));359 assert(bytes.len == @sizeOf(T));
371 var result: T = 0;360 var result: T = 0;
372 {comptime var i = 0; inline while (i < @sizeOf(T)) : (i += 1) {361 {
373 result |= T(bytes[i]) << i * 8;362 comptime var i = 0;
374 }}363 inline while (i < @sizeOf(T)) : (i += 1) {
364 result |= T(bytes[i]) << i * 8;
365 }
366 }
375 return result;367 return result;
376}368}
377369
...@@ -393,7 +385,7 @@ pub fn writeInt(buf: []u8, value: var, endian: builtin.Endian) void {...@@ -393,7 +385,7 @@ pub fn writeInt(buf: []u8, value: var, endian: builtin.Endian) void {
393 },385 },
394 builtin.Endian.Little => {386 builtin.Endian.Little => {
395 for (buf) |*b| {387 for (buf) |*b| {
396 *b = @truncate(u8, bits);388 b.* = @truncate(u8, bits);
397 bits >>= 8;389 bits >>= 8;
398 }390 }
399 },391 },
...@@ -401,7 +393,6 @@ pub fn writeInt(buf: []u8, value: var, endian: builtin.Endian) void {...@@ -401,7 +393,6 @@ pub fn writeInt(buf: []u8, value: var, endian: builtin.Endian) void {
401 assert(bits == 0);393 assert(bits == 0);
402}394}
403395
404
405pub fn hash_slice_u8(k: []const u8) u32 {396pub fn hash_slice_u8(k: []const u8) u32 {
406 // FNV 32-bit hash397 // FNV 32-bit hash
407 var h: u32 = 2166136261;398 var h: u32 = 2166136261;
...@@ -420,7 +411,7 @@ pub fn eql_slice_u8(a: []const u8, b: []const u8) bool {...@@ -420,7 +411,7 @@ pub fn eql_slice_u8(a: []const u8, b: []const u8) bool {
420/// split(" abc def ghi ", " ")411/// split(" abc def ghi ", " ")
421/// Will return slices for "abc", "def", "ghi", null, in that order.412/// Will return slices for "abc", "def", "ghi", null, in that order.
422pub fn split(buffer: []const u8, split_bytes: []const u8) SplitIterator {413pub fn split(buffer: []const u8, split_bytes: []const u8) SplitIterator {
423 return SplitIterator {414 return SplitIterator{
424 .index = 0,415 .index = 0,
425 .buffer = buffer,416 .buffer = buffer,
426 .split_bytes = split_bytes,417 .split_bytes = split_bytes,
...@@ -436,7 +427,7 @@ test "mem.split" {...@@ -436,7 +427,7 @@ test "mem.split" {
436}427}
437428
438pub fn startsWith(comptime T: type, haystack: []const T, needle: []const T) bool {429pub fn startsWith(comptime T: type, haystack: []const T, needle: []const T) bool {
439 return if (needle.len > haystack.len) false else eql(T, haystack[0 .. needle.len], needle);430 return if (needle.len > haystack.len) false else eql(T, haystack[0..needle.len], needle);
440}431}
441432
442test "mem.startsWith" {433test "mem.startsWith" {
...@@ -445,10 +436,9 @@ test "mem.startsWith" {...@@ -445,10 +436,9 @@ test "mem.startsWith" {
445}436}
446437
447pub fn endsWith(comptime T: type, haystack: []const T, needle: []const T) bool {438pub fn endsWith(comptime T: type, haystack: []const T, needle: []const T) bool {
448 return if (needle.len > haystack.len) false else eql(T, haystack[haystack.len - needle.len ..], needle);439 return if (needle.len > haystack.len) false else eql(T, haystack[haystack.len - needle.len..], needle);
449}440}
450441
451
452test "mem.endsWith" {442test "mem.endsWith" {
453 assert(endsWith(u8, "Needle in haystack", "haystack"));443 assert(endsWith(u8, "Needle in haystack", "haystack"));
454 assert(!endsWith(u8, "Bob", "Bo"));444 assert(!endsWith(u8, "Bob", "Bo"));
...@@ -542,29 +532,47 @@ test "testReadInt" {...@@ -542,29 +532,47 @@ test "testReadInt" {
542}532}
543fn testReadIntImpl() void {533fn testReadIntImpl() void {
544 {534 {
545 const bytes = []u8{ 0x12, 0x34, 0x56, 0x78 };535 const bytes = []u8{
546 assert(readInt(bytes, u32, builtin.Endian.Big) == 0x12345678);536 0x12,
547 assert(readIntBE(u32, bytes) == 0x12345678);537 0x34,
548 assert(readIntBE(i32, bytes) == 0x12345678);538 0x56,
539 0x78,
540 };
541 assert(readInt(bytes, u32, builtin.Endian.Big) == 0x12345678);
542 assert(readIntBE(u32, bytes) == 0x12345678);
543 assert(readIntBE(i32, bytes) == 0x12345678);
549 assert(readInt(bytes, u32, builtin.Endian.Little) == 0x78563412);544 assert(readInt(bytes, u32, builtin.Endian.Little) == 0x78563412);
550 assert(readIntLE(u32, bytes) == 0x78563412);545 assert(readIntLE(u32, bytes) == 0x78563412);
551 assert(readIntLE(i32, bytes) == 0x78563412);546 assert(readIntLE(i32, bytes) == 0x78563412);
552 }547 }
553 {548 {
554 const buf = []u8{0x00, 0x00, 0x12, 0x34};549 const buf = []u8{
550 0x00,
551 0x00,
552 0x12,
553 0x34,
554 };
555 const answer = readInt(buf, u64, builtin.Endian.Big);555 const answer = readInt(buf, u64, builtin.Endian.Big);
556 assert(answer == 0x00001234);556 assert(answer == 0x00001234);
557 }557 }
558 {558 {
559 const buf = []u8{0x12, 0x34, 0x00, 0x00};559 const buf = []u8{
560 0x12,
561 0x34,
562 0x00,
563 0x00,
564 };
560 const answer = readInt(buf, u64, builtin.Endian.Little);565 const answer = readInt(buf, u64, builtin.Endian.Little);
561 assert(answer == 0x00003412);566 assert(answer == 0x00003412);
562 }567 }
563 {568 {
564 const bytes = []u8{0xff, 0xfe};569 const bytes = []u8{
565 assert(readIntBE(u16, bytes) == 0xfffe);570 0xff,
571 0xfe,
572 };
573 assert(readIntBE(u16, bytes) == 0xfffe);
566 assert(readIntBE(i16, bytes) == -0x0002);574 assert(readIntBE(i16, bytes) == -0x0002);
567 assert(readIntLE(u16, bytes) == 0xfeff);575 assert(readIntLE(u16, bytes) == 0xfeff);
568 assert(readIntLE(i16, bytes) == -0x0101);576 assert(readIntLE(i16, bytes) == -0x0101);
569 }577 }
570}578}
...@@ -577,19 +585,38 @@ fn testWriteIntImpl() void {...@@ -577,19 +585,38 @@ fn testWriteIntImpl() void {
577 var bytes: [4]u8 = undefined;585 var bytes: [4]u8 = undefined;
578586
579 writeInt(bytes[0..], u32(0x12345678), builtin.Endian.Big);587 writeInt(bytes[0..], u32(0x12345678), builtin.Endian.Big);
580 assert(eql(u8, bytes, []u8{ 0x12, 0x34, 0x56, 0x78 }));588 assert(eql(u8, bytes, []u8{
589 0x12,
590 0x34,
591 0x56,
592 0x78,
593 }));
581594
582 writeInt(bytes[0..], u32(0x78563412), builtin.Endian.Little);595 writeInt(bytes[0..], u32(0x78563412), builtin.Endian.Little);
583 assert(eql(u8, bytes, []u8{ 0x12, 0x34, 0x56, 0x78 }));596 assert(eql(u8, bytes, []u8{
597 0x12,
598 0x34,
599 0x56,
600 0x78,
601 }));
584602
585 writeInt(bytes[0..], u16(0x1234), builtin.Endian.Big);603 writeInt(bytes[0..], u16(0x1234), builtin.Endian.Big);
586 assert(eql(u8, bytes, []u8{ 0x00, 0x00, 0x12, 0x34 }));604 assert(eql(u8, bytes, []u8{
605 0x00,
606 0x00,
607 0x12,
608 0x34,
609 }));
587610
588 writeInt(bytes[0..], u16(0x1234), builtin.Endian.Little);611 writeInt(bytes[0..], u16(0x1234), builtin.Endian.Little);
589 assert(eql(u8, bytes, []u8{ 0x34, 0x12, 0x00, 0x00 }));612 assert(eql(u8, bytes, []u8{
613 0x34,
614 0x12,
615 0x00,
616 0x00,
617 }));
590}618}
591619
592
593pub fn min(comptime T: type, slice: []const T) T {620pub fn min(comptime T: type, slice: []const T) T {
594 var best = slice[0];621 var best = slice[0];
595 for (slice[1..]) |item| {622 for (slice[1..]) |item| {
...@@ -615,9 +642,9 @@ test "mem.max" {...@@ -615,9 +642,9 @@ test "mem.max" {
615}642}
616643
617pub fn swap(comptime T: type, a: &T, b: &T) void {644pub fn swap(comptime T: type, a: &T, b: &T) void {
618 const tmp = *a;645 const tmp = a.*;
619 *a = *b;646 a.* = b.*;
620 *b = tmp;647 b.* = tmp;
621}648}
622649
623/// In-place order reversal of a slice650/// In-place order reversal of a slice
...@@ -630,10 +657,22 @@ pub fn reverse(comptime T: type, items: []T) void {...@@ -630,10 +657,22 @@ pub fn reverse(comptime T: type, items: []T) void {
630}657}
631658
632test "std.mem.reverse" {659test "std.mem.reverse" {
633 var arr = []i32{ 5, 3, 1, 2, 4 };660 var arr = []i32{
661 5,
662 3,
663 1,
664 2,
665 4,
666 };
634 reverse(i32, arr[0..]);667 reverse(i32, arr[0..]);
635668
636 assert(eql(i32, arr, []i32{ 4, 2, 1, 3, 5 }));669 assert(eql(i32, arr, []i32{
670 4,
671 2,
672 1,
673 3,
674 5,
675 }));
637}676}
638677
639/// In-place rotation of the values in an array ([0 1 2 3] becomes [1 2 3 0] if we rotate by 1)678/// In-place rotation of the values in an array ([0 1 2 3] becomes [1 2 3 0] if we rotate by 1)
...@@ -645,10 +684,22 @@ pub fn rotate(comptime T: type, items: []T, amount: usize) void {...@@ -645,10 +684,22 @@ pub fn rotate(comptime T: type, items: []T, amount: usize) void {
645}684}
646685
647test "std.mem.rotate" {686test "std.mem.rotate" {
648 var arr = []i32{ 5, 3, 1, 2, 4 };687 var arr = []i32{
688 5,
689 3,
690 1,
691 2,
692 4,
693 };
649 rotate(i32, arr[0..], 2);694 rotate(i32, arr[0..], 2);
650695
651 assert(eql(i32, arr, []i32{ 1, 2, 4, 5, 3 }));696 assert(eql(i32, arr, []i32{
697 1,
698 2,
699 4,
700 5,
701 3,
702 }));
652}703}
653704
654// TODO: When https://github.com/zig-lang/zig/issues/649 is solved these can be done by705// TODO: When https://github.com/zig-lang/zig/issues/649 is solved these can be done by
std/zig/parser.zig+7-2
...@@ -3705,7 +3705,9 @@ pub const Parser = struct {...@@ -3705,7 +3705,9 @@ pub const Parser = struct {
3705 },3705 },
3706 ast.Node.Id.PrefixOp => {3706 ast.Node.Id.PrefixOp => {
3707 const prefix_op_node = @fieldParentPtr(ast.Node.PrefixOp, "base", base);3707 const prefix_op_node = @fieldParentPtr(ast.Node.PrefixOp, "base", base);
3708 try stack.append(RenderState { .Expression = prefix_op_node.rhs });3708 if (prefix_op_node.op != ast.Node.PrefixOp.Op.Deref) {
3709 try stack.append(RenderState { .Expression = prefix_op_node.rhs });
3710 }
3709 switch (prefix_op_node.op) {3711 switch (prefix_op_node.op) {
3710 ast.Node.PrefixOp.Op.AddrOf => |addr_of_info| {3712 ast.Node.PrefixOp.Op.AddrOf => |addr_of_info| {
3711 try stream.write("&");3713 try stream.write("&");
...@@ -3742,7 +3744,10 @@ pub const Parser = struct {...@@ -3742,7 +3744,10 @@ pub const Parser = struct {
3742 },3744 },
3743 ast.Node.PrefixOp.Op.BitNot => try stream.write("~"),3745 ast.Node.PrefixOp.Op.BitNot => try stream.write("~"),
3744 ast.Node.PrefixOp.Op.BoolNot => try stream.write("!"),3746 ast.Node.PrefixOp.Op.BoolNot => try stream.write("!"),
3745 ast.Node.PrefixOp.Op.Deref => try stream.write("*"),3747 ast.Node.PrefixOp.Op.Deref => {
3748 try stack.append(RenderState { .Text = ".*" });
3749 try stack.append(RenderState { .Expression = prefix_op_node.rhs });
3750 },
3746 ast.Node.PrefixOp.Op.Negation => try stream.write("-"),3751 ast.Node.PrefixOp.Op.Negation => try stream.write("-"),
3747 ast.Node.PrefixOp.Op.NegationWrap => try stream.write("-%"),3752 ast.Node.PrefixOp.Op.NegationWrap => try stream.write("-%"),
3748 ast.Node.PrefixOp.Op.Try => try stream.write("try "),3753 ast.Node.PrefixOp.Op.Try => try stream.write("try "),
test/cases/align.zig+60-26
...@@ -10,7 +10,9 @@ test "global variable alignment" {...@@ -10,7 +10,9 @@ test "global variable alignment" {
10 assert(@typeOf(slice) == []align(4) u8);10 assert(@typeOf(slice) == []align(4) u8);
11}11}
1212
13fn derp() align(@sizeOf(usize) * 2) i32 { return 1234; }13fn derp() align(@sizeOf(usize) * 2) i32 {
14 return 1234;
15}
14fn noop1() align(1) void {}16fn noop1() align(1) void {}
15fn noop4() align(4) void {}17fn noop4() align(4) void {}
1618
...@@ -22,7 +24,6 @@ test "function alignment" {...@@ -22,7 +24,6 @@ test "function alignment" {
22 noop4();24 noop4();
23}25}
2426
25
26var baz: packed struct {27var baz: packed struct {
27 a: u32,28 a: u32,
28 b: u32,29 b: u32,
...@@ -32,7 +33,6 @@ test "packed struct alignment" {...@@ -32,7 +33,6 @@ test "packed struct alignment" {
32 assert(@typeOf(&baz.b) == &align(1) u32);33 assert(@typeOf(&baz.b) == &align(1) u32);
33}34}
3435
35
36const blah: packed struct {36const blah: packed struct {
37 a: u3,37 a: u3,
38 b: u3,38 b: u3,
...@@ -53,29 +53,43 @@ test "implicitly decreasing pointer alignment" {...@@ -53,29 +53,43 @@ test "implicitly decreasing pointer alignment" {
53 assert(addUnaligned(&a, &b) == 7);53 assert(addUnaligned(&a, &b) == 7);
54}54}
5555
56fn addUnaligned(a: &align(1) const u32, b: &align(1) const u32) u32 { return *a + *b; }56fn addUnaligned(a: &align(1) const u32, b: &align(1) const u32) u32 {
57 return a.* + b.*;
58}
5759
58test "implicitly decreasing slice alignment" {60test "implicitly decreasing slice alignment" {
59 const a: u32 align(4) = 3;61 const a: u32 align(4) = 3;
60 const b: u32 align(8) = 4;62 const b: u32 align(8) = 4;
61 assert(addUnalignedSlice((&a)[0..1], (&b)[0..1]) == 7);63 assert(addUnalignedSlice((&a)[0..1], (&b)[0..1]) == 7);
62}64}
63fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) u32 { return a[0] + b[0]; }65fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) u32 {
66 return a[0] + b[0];
67}
6468
65test "specifying alignment allows pointer cast" {69test "specifying alignment allows pointer cast" {
66 testBytesAlign(0x33);70 testBytesAlign(0x33);
67}71}
68fn testBytesAlign(b: u8) void {72fn testBytesAlign(b: u8) void {
69 var bytes align(4) = []u8{b, b, b, b};73 var bytes align(4) = []u8 {
74 b,
75 b,
76 b,
77 b,
78 };
70 const ptr = @ptrCast(&u32, &bytes[0]);79 const ptr = @ptrCast(&u32, &bytes[0]);
71 assert(*ptr == 0x33333333);80 assert(ptr.* == 0x33333333);
72}81}
7382
74test "specifying alignment allows slice cast" {83test "specifying alignment allows slice cast" {
75 testBytesAlignSlice(0x33);84 testBytesAlignSlice(0x33);
76}85}
77fn testBytesAlignSlice(b: u8) void {86fn testBytesAlignSlice(b: u8) void {
78 var bytes align(4) = []u8{b, b, b, b};87 var bytes align(4) = []u8 {
88 b,
89 b,
90 b,
91 b,
92 };
79 const slice = ([]u32)(bytes[0..]);93 const slice = ([]u32)(bytes[0..]);
80 assert(slice[0] == 0x33333333);94 assert(slice[0] == 0x33333333);
81}95}
...@@ -89,11 +103,14 @@ fn expectsOnly1(x: &align(1) u32) void {...@@ -89,11 +103,14 @@ fn expectsOnly1(x: &align(1) u32) void {
89 expects4(@alignCast(4, x));103 expects4(@alignCast(4, x));
90}104}
91fn expects4(x: &align(4) u32) void {105fn expects4(x: &align(4) u32) void {
92 *x += 1;106 x.* += 1;
93}107}
94108
95test "@alignCast slices" {109test "@alignCast slices" {
96 var array align(4) = []u32{1, 1};110 var array align(4) = []u32 {
111 1,
112 1,
113 };
97 const slice = array[0..];114 const slice = array[0..];
98 sliceExpectsOnly1(slice);115 sliceExpectsOnly1(slice);
99 assert(slice[0] == 2);116 assert(slice[0] == 2);
...@@ -105,31 +122,34 @@ fn sliceExpects4(slice: []align(4) u32) void {...@@ -105,31 +122,34 @@ fn sliceExpects4(slice: []align(4) u32) void {
105 slice[0] += 1;122 slice[0] += 1;
106}123}
107124
108
109test "implicitly decreasing fn alignment" {125test "implicitly decreasing fn alignment" {
110 testImplicitlyDecreaseFnAlign(alignedSmall, 1234);126 testImplicitlyDecreaseFnAlign(alignedSmall, 1234);
111 testImplicitlyDecreaseFnAlign(alignedBig, 5678);127 testImplicitlyDecreaseFnAlign(alignedBig, 5678);
112}128}
113129
114fn testImplicitlyDecreaseFnAlign(ptr: fn () align(1) i32, answer: i32) void {130fn testImplicitlyDecreaseFnAlign(ptr: fn() align(1) i32, answer: i32) void {
115 assert(ptr() == answer);131 assert(ptr() == answer);
116}132}
117133
118fn alignedSmall() align(8) i32 { return 1234; }134fn alignedSmall() align(8) i32 {
119fn alignedBig() align(16) i32 { return 5678; }135 return 1234;
120136}
137fn alignedBig() align(16) i32 {
138 return 5678;
139}
121140
122test "@alignCast functions" {141test "@alignCast functions" {
123 assert(fnExpectsOnly1(simple4) == 0x19);142 assert(fnExpectsOnly1(simple4) == 0x19);
124}143}
125fn fnExpectsOnly1(ptr: fn()align(1) i32) i32 {144fn fnExpectsOnly1(ptr: fn() align(1) i32) i32 {
126 return fnExpects4(@alignCast(4, ptr));145 return fnExpects4(@alignCast(4, ptr));
127}146}
128fn fnExpects4(ptr: fn()align(4) i32) i32 {147fn fnExpects4(ptr: fn() align(4) i32) i32 {
129 return ptr();148 return ptr();
130}149}
131fn simple4() align(4) i32 { return 0x19; }150fn simple4() align(4) i32 {
132151 return 0x19;
152}
133153
134test "generic function with align param" {154test "generic function with align param" {
135 assert(whyWouldYouEverDoThis(1) == 0x1);155 assert(whyWouldYouEverDoThis(1) == 0x1);
...@@ -137,8 +157,9 @@ test "generic function with align param" {...@@ -137,8 +157,9 @@ test "generic function with align param" {
137 assert(whyWouldYouEverDoThis(8) == 0x1);157 assert(whyWouldYouEverDoThis(8) == 0x1);
138}158}
139159
140fn whyWouldYouEverDoThis(comptime align_bytes: u8) align(align_bytes) u8 { return 0x1; }160fn whyWouldYouEverDoThis(comptime align_bytes: u8) align(align_bytes) u8 {
141161 return 0x1;
162}
142163
143test "@ptrCast preserves alignment of bigger source" {164test "@ptrCast preserves alignment of bigger source" {
144 var x: u32 align(16) = 1234;165 var x: u32 align(16) = 1234;
...@@ -146,24 +167,38 @@ test "@ptrCast preserves alignment of bigger source" {...@@ -146,24 +167,38 @@ test "@ptrCast preserves alignment of bigger source" {
146 assert(@typeOf(ptr) == &align(16) u8);167 assert(@typeOf(ptr) == &align(16) u8);
147}168}
148169
149
150test "compile-time known array index has best alignment possible" {170test "compile-time known array index has best alignment possible" {
151 // take full advantage of over-alignment171 // take full advantage of over-alignment
152 var array align(4) = []u8 {1, 2, 3, 4};172 var array align(4) = []u8 {
173 1,
174 2,
175 3,
176 4,
177 };
153 assert(@typeOf(&array[0]) == &align(4) u8);178 assert(@typeOf(&array[0]) == &align(4) u8);
154 assert(@typeOf(&array[1]) == &u8);179 assert(@typeOf(&array[1]) == &u8);
155 assert(@typeOf(&array[2]) == &align(2) u8);180 assert(@typeOf(&array[2]) == &align(2) u8);
156 assert(@typeOf(&array[3]) == &u8);181 assert(@typeOf(&array[3]) == &u8);
157182
158 // because align is too small but we still figure out to use 2183 // because align is too small but we still figure out to use 2
159 var bigger align(2) = []u64{1, 2, 3, 4};184 var bigger align(2) = []u64 {
185 1,
186 2,
187 3,
188 4,
189 };
160 assert(@typeOf(&bigger[0]) == &align(2) u64);190 assert(@typeOf(&bigger[0]) == &align(2) u64);
161 assert(@typeOf(&bigger[1]) == &align(2) u64);191 assert(@typeOf(&bigger[1]) == &align(2) u64);
162 assert(@typeOf(&bigger[2]) == &align(2) u64);192 assert(@typeOf(&bigger[2]) == &align(2) u64);
163 assert(@typeOf(&bigger[3]) == &align(2) u64);193 assert(@typeOf(&bigger[3]) == &align(2) u64);
164194
165 // because pointer is align 2 and u32 align % 2 == 0 we can assume align 2195 // because pointer is align 2 and u32 align % 2 == 0 we can assume align 2
166 var smaller align(2) = []u32{1, 2, 3, 4};196 var smaller align(2) = []u32 {
197 1,
198 2,
199 3,
200 4,
201 };
167 testIndex(&smaller[0], 0, &align(2) u32);202 testIndex(&smaller[0], 0, &align(2) u32);
168 testIndex(&smaller[0], 1, &align(2) u32);203 testIndex(&smaller[0], 1, &align(2) u32);
169 testIndex(&smaller[0], 2, &align(2) u32);204 testIndex(&smaller[0], 2, &align(2) u32);
...@@ -182,7 +217,6 @@ fn testIndex2(ptr: &align(4) u8, index: usize, comptime T: type) void {...@@ -182,7 +217,6 @@ fn testIndex2(ptr: &align(4) u8, index: usize, comptime T: type) void {
182 assert(@typeOf(&ptr[index]) == T);217 assert(@typeOf(&ptr[index]) == T);
183}218}
184219
185
186test "alignstack" {220test "alignstack" {
187 assert(fnWithAlignedStack() == 1234);221 assert(fnWithAlignedStack() == 1234);
188}222}
test/cases/alignof.zig+5-1
...@@ -1,7 +1,11 @@...@@ -1,7 +1,11 @@
1const assert = @import("std").debug.assert;1const assert = @import("std").debug.assert;
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4const Foo = struct { x: u32, y: u32, z: u32, };4const Foo = struct {
5 x: u32,
6 y: u32,
7 z: u32,
8};
59
6test "@alignOf(T) before referencing T" {10test "@alignOf(T) before referencing T" {
7 comptime assert(@alignOf(Foo) != @maxValue(usize));11 comptime assert(@alignOf(Foo) != @maxValue(usize));
test/cases/array.zig+31-10
...@@ -2,9 +2,9 @@ const assert = @import("std").debug.assert;...@@ -2,9 +2,9 @@ const assert = @import("std").debug.assert;
2const mem = @import("std").mem;2const mem = @import("std").mem;
33
4test "arrays" {4test "arrays" {
5 var array : [5]u32 = undefined;5 var array: [5]u32 = undefined;
66
7 var i : u32 = 0;7 var i: u32 = 0;
8 while (i < 5) {8 while (i < 5) {
9 array[i] = i + 1;9 array[i] = i + 1;
10 i = array[i];10 i = array[i];
...@@ -34,24 +34,41 @@ test "void arrays" {...@@ -34,24 +34,41 @@ test "void arrays" {
34}34}
3535
36test "array literal" {36test "array literal" {
37 const hex_mult = []u16{4096, 256, 16, 1};37 const hex_mult = []u16 {
38 4096,
39 256,
40 16,
41 1,
42 };
3843
39 assert(hex_mult.len == 4);44 assert(hex_mult.len == 4);
40 assert(hex_mult[1] == 256);45 assert(hex_mult[1] == 256);
41}46}
4247
43test "array dot len const expr" {48test "array dot len const expr" {
44 assert(comptime x: {break :x some_array.len == 4;});49 assert(comptime x: {
50 break :x some_array.len == 4;
51 });
45}52}
4653
47const ArrayDotLenConstExpr = struct {54const ArrayDotLenConstExpr = struct {
48 y: [some_array.len]u8,55 y: [some_array.len]u8,
49};56};
50const some_array = []u8 {0, 1, 2, 3};57const some_array = []u8 {
5158 0,
59 1,
60 2,
61 3,
62};
5263
53test "nested arrays" {64test "nested arrays" {
54 const array_of_strings = [][]const u8 {"hello", "this", "is", "my", "thing"};65 const array_of_strings = [][]const u8 {
66 "hello",
67 "this",
68 "is",
69 "my",
70 "thing",
71 };
55 for (array_of_strings) |s, i| {72 for (array_of_strings) |s, i| {
56 if (i == 0) assert(mem.eql(u8, s, "hello"));73 if (i == 0) assert(mem.eql(u8, s, "hello"));
57 if (i == 1) assert(mem.eql(u8, s, "this"));74 if (i == 1) assert(mem.eql(u8, s, "this"));
...@@ -61,7 +78,6 @@ test "nested arrays" {...@@ -61,7 +78,6 @@ test "nested arrays" {
61 }78 }
62}79}
6380
64
65var s_array: [8]Sub = undefined;81var s_array: [8]Sub = undefined;
66const Sub = struct {82const Sub = struct {
67 b: u8,83 b: u8,
...@@ -70,7 +86,9 @@ const Str = struct {...@@ -70,7 +86,9 @@ const Str = struct {
70 a: []Sub,86 a: []Sub,
71};87};
72test "set global var array via slice embedded in struct" {88test "set global var array via slice embedded in struct" {
73 var s = Str { .a = s_array[0..]};89 var s = Str {
90 .a = s_array[0..],
91 };
7492
75 s.a[0].b = 1;93 s.a[0].b = 1;
76 s.a[1].b = 2;94 s.a[1].b = 2;
...@@ -82,7 +100,10 @@ test "set global var array via slice embedded in struct" {...@@ -82,7 +100,10 @@ test "set global var array via slice embedded in struct" {
82}100}
83101
84test "array literal with specified size" {102test "array literal with specified size" {
85 var array = [2]u8{1, 2};103 var array = [2]u8 {
104 1,
105 2,
106 };
86 assert(array[0] == 1);107 assert(array[0] == 1);
87 assert(array[1] == 2);108 assert(array[1] == 2);
88}109}
test/cases/bitcast.zig+6-2
...@@ -10,5 +10,9 @@ fn testBitCast_i32_u32() void {...@@ -10,5 +10,9 @@ fn testBitCast_i32_u32() void {
10 assert(conv2(@maxValue(u32)) == -1);10 assert(conv2(@maxValue(u32)) == -1);
11}11}
1212
13fn conv(x: i32) u32 { return @bitCast(u32, x); }13fn conv(x: i32) u32 {
14fn conv2(x: u32) i32 { return @bitCast(i32, x); }14 return @bitCast(u32, x);
15}
16fn conv2(x: u32) i32 {
17 return @bitCast(i32, x);
18}
test/cases/bugs/394.zig+14-3
...@@ -1,9 +1,20 @@...@@ -1,9 +1,20 @@
1const E = union(enum) { A: [9]u8, B: u64, };1const E = union(enum) {
2const S = struct { x: u8, y: E, };2 A: [9]u8,
3 B: u64,
4};
5const S = struct {
6 x: u8,
7 y: E,
8};
39
4const assert = @import("std").debug.assert;10const assert = @import("std").debug.assert;
511
6test "bug 394 fixed" {12test "bug 394 fixed" {
7 const x = S { .x = 3, .y = E {.B = 1 } };13 const x = S {
14 .x = 3,
15 .y = E {
16 .B = 1,
17 },
18 };
8 assert(x.x == 3);19 assert(x.x == 3);
9}20}
test/cases/bugs/655.zig+1-1
...@@ -8,5 +8,5 @@ test "function with &const parameter with type dereferenced by namespace" {...@@ -8,5 +8,5 @@ test "function with &const parameter with type dereferenced by namespace" {
8}8}
99
10fn foo(x: &const other_file.Integer) void {10fn foo(x: &const other_file.Integer) void {
11 std.debug.assert(*x == 1234);11 std.debug.assert(x.* == 1234);
12}12}
test/cases/bugs/656.zig+7-4
...@@ -14,12 +14,15 @@ test "nullable if after an if in a switch prong of a switch with 2 prongs in an...@@ -14,12 +14,15 @@ test "nullable if after an if in a switch prong of a switch with 2 prongs in an
14}14}
1515
16fn foo(a: bool, b: bool) void {16fn foo(a: bool, b: bool) void {
17 var prefix_op = PrefixOp { .AddrOf = Value { .align_expr = 1234 } };17 var prefix_op = PrefixOp {
18 if (a) {18 .AddrOf = Value {
19 } else {19 .align_expr = 1234,
20 },
21 };
22 if (a) {} else {
20 switch (prefix_op) {23 switch (prefix_op) {
21 PrefixOp.AddrOf => |addr_of_info| {24 PrefixOp.AddrOf => |addr_of_info| {
22 if (b) { }25 if (b) {}
23 if (addr_of_info.align_expr) |align_expr| {26 if (addr_of_info.align_expr) |align_expr| {
24 assert(align_expr == 1234);27 assert(align_expr == 1234);
25 }28 }
test/cases/bugs/828.zig+5-5
...@@ -1,10 +1,10 @@...@@ -1,10 +1,10 @@
1const CountBy = struct {1const CountBy = struct {
2 a: usize,2 a: usize,
3 3
4 const One = CountBy {4 const One = CountBy {
5 .a = 1,5 .a = 1,
6 };6 };
7 7
8 pub fn counter(self: &const CountBy) Counter {8 pub fn counter(self: &const CountBy) Counter {
9 return Counter {9 return Counter {
10 .i = 0,10 .i = 0,
...@@ -14,7 +14,7 @@ const CountBy = struct {...@@ -14,7 +14,7 @@ const CountBy = struct {
1414
15const Counter = struct {15const Counter = struct {
16 i: usize,16 i: usize,
17 17
18 pub fn count(self: &Counter) bool {18 pub fn count(self: &Counter) bool {
19 self.i += 1;19 self.i += 1;
20 return self.i <= 10;20 return self.i <= 10;
...@@ -24,8 +24,8 @@ const Counter = struct {...@@ -24,8 +24,8 @@ const Counter = struct {
24fn constCount(comptime cb: &const CountBy, comptime unused: u32) void {24fn constCount(comptime cb: &const CountBy, comptime unused: u32) void {
25 comptime {25 comptime {
26 var cnt = cb.counter();26 var cnt = cb.counter();
27 if(cnt.i != 0) @compileError("Counter instance reused!");27 if (cnt.i != 0) @compileError("Counter instance reused!");
28 while(cnt.count()){}28 while (cnt.count()) {}
29 }29 }
30}30}
3131
test/cases/bugs/920.zig+12-7
...@@ -12,8 +12,7 @@ const ZigTable = struct {...@@ -12,8 +12,7 @@ const ZigTable = struct {
12 zero_case: fn(&Random, f64) f64,12 zero_case: fn(&Random, f64) f64,
13};13};
1414
15fn ZigTableGen(comptime is_symmetric: bool, comptime r: f64, comptime v: f64, comptime f: fn(f64) f64,15fn ZigTableGen(comptime is_symmetric: bool, comptime r: f64, comptime v: f64, comptime f: fn(f64) f64, comptime f_inv: fn(f64) f64, comptime zero_case: fn(&Random, f64) f64) ZigTable {
16 comptime f_inv: fn(f64) f64, comptime zero_case: fn(&Random, f64) f64) ZigTable {
17 var tables: ZigTable = undefined;16 var tables: ZigTable = undefined;
1817
19 tables.is_symmetric = is_symmetric;18 tables.is_symmetric = is_symmetric;
...@@ -26,12 +25,12 @@ fn ZigTableGen(comptime is_symmetric: bool, comptime r: f64, comptime v: f64, co...@@ -26,12 +25,12 @@ fn ZigTableGen(comptime is_symmetric: bool, comptime r: f64, comptime v: f64, co
2625
27 for (tables.x[2..256]) |*entry, i| {26 for (tables.x[2..256]) |*entry, i| {
28 const last = tables.x[2 + i - 1];27 const last = tables.x[2 + i - 1];
29 *entry = f_inv(v / last + f(last));28 entry.* = f_inv(v / last + f(last));
30 }29 }
31 tables.x[256] = 0;30 tables.x[256] = 0;
3231
33 for (tables.f[0..]) |*entry, i| {32 for (tables.f[0..]) |*entry, i| {
34 *entry = f(tables.x[i]);33 entry.* = f(tables.x[i]);
35 }34 }
3635
37 return tables;36 return tables;
...@@ -40,9 +39,15 @@ fn ZigTableGen(comptime is_symmetric: bool, comptime r: f64, comptime v: f64, co...@@ -40,9 +39,15 @@ fn ZigTableGen(comptime is_symmetric: bool, comptime r: f64, comptime v: f64, co
40const norm_r = 3.6541528853610088;39const norm_r = 3.6541528853610088;
41const norm_v = 0.00492867323399;40const norm_v = 0.00492867323399;
4241
43fn norm_f(x: f64) f64 { return math.exp(-x * x / 2.0); }42fn norm_f(x: f64) f64 {
44fn norm_f_inv(y: f64) f64 { return math.sqrt(-2.0 * math.ln(y)); }43 return math.exp(-x * x / 2.0);
45fn norm_zero_case(random: &Random, u: f64) f64 { return 0.0; }44}
45fn norm_f_inv(y: f64) f64 {
46 return math.sqrt(-2.0 * math.ln(y));
47}
48fn norm_zero_case(random: &Random, u: f64) f64 {
49 return 0.0;
50}
4651
47const NormalDist = blk: {52const NormalDist = blk: {
48 @setEvalBranchQuota(30000);53 @setEvalBranchQuota(30000);
test/cases/cast.zig+43-29
...@@ -14,10 +14,10 @@ test "integer literal to pointer cast" {...@@ -14,10 +14,10 @@ test "integer literal to pointer cast" {
14}14}
1515
16test "pointer reinterpret const float to int" {16test "pointer reinterpret const float to int" {
17 const float: f64 = 5.99999999999994648725e-01;17 const float: f64 = 5.99999999999994648725e - 01;
18 const float_ptr = &float;18 const float_ptr = &float;
19 const int_ptr = @ptrCast(&const i32, float_ptr);19 const int_ptr = @ptrCast(&const i32, float_ptr);
20 const int_val = *int_ptr;20 const int_val = int_ptr.*;
21 assert(int_val == 858993411);21 assert(int_val == 858993411);
22}22}
2323
...@@ -29,25 +29,31 @@ test "implicitly cast a pointer to a const pointer of it" {...@@ -29,25 +29,31 @@ test "implicitly cast a pointer to a const pointer of it" {
29}29}
3030
31fn funcWithConstPtrPtr(x: &const &i32) void {31fn funcWithConstPtrPtr(x: &const &i32) void {
32 **x += 1;32 x.*.* += 1;
33}33}
3434
35test "implicitly cast a container to a const pointer of it" {35test "implicitly cast a container to a const pointer of it" {
36 const z = Struct(void) { .x = void{} };36 const z = Struct(void) {
37 .x = void{},
38 };
37 assert(0 == @sizeOf(@typeOf(z)));39 assert(0 == @sizeOf(@typeOf(z)));
38 assert(void{} == Struct(void).pointer(z).x);40 assert(void{} == Struct(void).pointer(z).x);
39 assert(void{} == Struct(void).pointer(&z).x);41 assert(void{} == Struct(void).pointer(&z).x);
40 assert(void{} == Struct(void).maybePointer(z).x);42 assert(void{} == Struct(void).maybePointer(z).x);
41 assert(void{} == Struct(void).maybePointer(&z).x);43 assert(void{} == Struct(void).maybePointer(&z).x);
42 assert(void{} == Struct(void).maybePointer(null).x);44 assert(void{} == Struct(void).maybePointer(null).x);
43 const s = Struct(u8) { .x = 42 };45 const s = Struct(u8) {
46 .x = 42,
47 };
44 assert(0 != @sizeOf(@typeOf(s)));48 assert(0 != @sizeOf(@typeOf(s)));
45 assert(42 == Struct(u8).pointer(s).x);49 assert(42 == Struct(u8).pointer(s).x);
46 assert(42 == Struct(u8).pointer(&s).x);50 assert(42 == Struct(u8).pointer(&s).x);
47 assert(42 == Struct(u8).maybePointer(s).x);51 assert(42 == Struct(u8).maybePointer(s).x);
48 assert(42 == Struct(u8).maybePointer(&s).x);52 assert(42 == Struct(u8).maybePointer(&s).x);
49 assert(0 == Struct(u8).maybePointer(null).x);53 assert(0 == Struct(u8).maybePointer(null).x);
50 const u = Union { .x = 42 };54 const u = Union {
55 .x = 42,
56 };
51 assert(42 == Union.pointer(u).x);57 assert(42 == Union.pointer(u).x);
52 assert(42 == Union.pointer(&u).x);58 assert(42 == Union.pointer(&u).x);
53 assert(42 == Union.maybePointer(u).x);59 assert(42 == Union.maybePointer(u).x);
...@@ -67,12 +73,14 @@ fn Struct(comptime T: type) type {...@@ -67,12 +73,14 @@ fn Struct(comptime T: type) type {
67 x: T,73 x: T,
6874
69 fn pointer(self: &const Self) Self {75 fn pointer(self: &const Self) Self {
70 return *self;76 return self.*;
71 }77 }
7278
73 fn maybePointer(self: ?&const Self) Self {79 fn maybePointer(self: ?&const Self) Self {
74 const none = Self { .x = if (T == void) void{} else 0 };80 const none = Self {
75 return *(self ?? &none);81 .x = if (T == void) void{} else 0,
82 };
83 return (self ?? &none).*;
76 }84 }
77 };85 };
78}86}
...@@ -81,12 +89,14 @@ const Union = union {...@@ -81,12 +89,14 @@ const Union = union {
81 x: u8,89 x: u8,
8290
83 fn pointer(self: &const Union) Union {91 fn pointer(self: &const Union) Union {
84 return *self;92 return self.*;
85 }93 }
8694
87 fn maybePointer(self: ?&const Union) Union {95 fn maybePointer(self: ?&const Union) Union {
88 const none = Union { .x = 0 };96 const none = Union {
89 return *(self ?? &none);97 .x = 0,
98 };
99 return (self ?? &none).*;
90 }100 }
91};101};
92102
...@@ -95,11 +105,11 @@ const Enum = enum {...@@ -95,11 +105,11 @@ const Enum = enum {
95 Some,105 Some,
96106
97 fn pointer(self: &const Enum) Enum {107 fn pointer(self: &const Enum) Enum {
98 return *self;108 return self.*;
99 }109 }
100110
101 fn maybePointer(self: ?&const Enum) Enum {111 fn maybePointer(self: ?&const Enum) Enum {
102 return *(self ?? &Enum.None);112 return (self ?? &Enum.None).*;
103 }113 }
104};114};
105115
...@@ -108,19 +118,21 @@ test "implicitly cast indirect pointer to maybe-indirect pointer" {...@@ -108,19 +118,21 @@ test "implicitly cast indirect pointer to maybe-indirect pointer" {
108 const Self = this;118 const Self = this;
109 x: u8,119 x: u8,
110 fn constConst(p: &const &const Self) u8 {120 fn constConst(p: &const &const Self) u8 {
111 return (*p).x;121 return (p.*).x;
112 }122 }
113 fn maybeConstConst(p: ?&const &const Self) u8 {123 fn maybeConstConst(p: ?&const &const Self) u8 {
114 return (*??p).x;124 return (??p.*).x;
115 }125 }
116 fn constConstConst(p: &const &const &const Self) u8 {126 fn constConstConst(p: &const &const &const Self) u8 {
117 return (**p).x;127 return (p.*.*).x;
118 }128 }
119 fn maybeConstConstConst(p: ?&const &const &const Self) u8 {129 fn maybeConstConstConst(p: ?&const &const &const Self) u8 {
120 return (**??p).x;130 return (??p.*.*).x;
121 }131 }
122 };132 };
123 const s = S { .x = 42 };133 const s = S {
134 .x = 42,
135 };
124 const p = &s;136 const p = &s;
125 const q = &p;137 const q = &p;
126 const r = &q;138 const r = &q;
...@@ -154,7 +166,6 @@ fn boolToStr(b: bool) []const u8 {...@@ -154,7 +166,6 @@ fn boolToStr(b: bool) []const u8 {
154 return if (b) "true" else "false";166 return if (b) "true" else "false";
155}167}
156168
157
158test "peer resolve array and const slice" {169test "peer resolve array and const slice" {
159 testPeerResolveArrayConstSlice(true);170 testPeerResolveArrayConstSlice(true);
160 comptime testPeerResolveArrayConstSlice(true);171 comptime testPeerResolveArrayConstSlice(true);
...@@ -168,12 +179,12 @@ fn testPeerResolveArrayConstSlice(b: bool) void {...@@ -168,12 +179,12 @@ fn testPeerResolveArrayConstSlice(b: bool) void {
168179
169test "integer literal to &const int" {180test "integer literal to &const int" {
170 const x: &const i32 = 3;181 const x: &const i32 = 3;
171 assert(*x == 3);182 assert(x.* == 3);
172}183}
173184
174test "string literal to &const []const u8" {185test "string literal to &const []const u8" {
175 const x: &const []const u8 = "hello";186 const x: &const []const u8 = "hello";
176 assert(mem.eql(u8, *x, "hello"));187 assert(mem.eql(u8, x.*, "hello"));
177}188}
178189
179test "implicitly cast from T to error!?T" {190test "implicitly cast from T to error!?T" {
...@@ -191,7 +202,9 @@ fn castToMaybeTypeError(z: i32) void {...@@ -191,7 +202,9 @@ fn castToMaybeTypeError(z: i32) void {
191 const f = z;202 const f = z;
192 const g: error!?i32 = f;203 const g: error!?i32 = f;
193204
194 const a = A{ .a = z };205 const a = A {
206 .a = z,
207 };
195 const b: error!?A = a;208 const b: error!?A = a;
196 assert((??(b catch unreachable)).a == 1);209 assert((??(b catch unreachable)).a == 1);
197}210}
...@@ -205,7 +218,6 @@ fn implicitIntLitToMaybe() void {...@@ -205,7 +218,6 @@ fn implicitIntLitToMaybe() void {
205 const g: error!?i32 = 1;218 const g: error!?i32 = 1;
206}219}
207220
208
209test "return null from fn() error!?&T" {221test "return null from fn() error!?&T" {
210 const a = returnNullFromMaybeTypeErrorRef();222 const a = returnNullFromMaybeTypeErrorRef();
211 const b = returnNullLitFromMaybeTypeErrorRef();223 const b = returnNullLitFromMaybeTypeErrorRef();
...@@ -235,7 +247,6 @@ fn peerTypeTAndMaybeT(c: bool, b: bool) ?usize {...@@ -235,7 +247,6 @@ fn peerTypeTAndMaybeT(c: bool, b: bool) ?usize {
235 return usize(3);247 return usize(3);
236}248}
237249
238
239test "peer type resolution: [0]u8 and []const u8" {250test "peer type resolution: [0]u8 and []const u8" {
240 assert(peerTypeEmptyArrayAndSlice(true, "hi").len == 0);251 assert(peerTypeEmptyArrayAndSlice(true, "hi").len == 0);
241 assert(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);252 assert(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);
...@@ -246,7 +257,7 @@ test "peer type resolution: [0]u8 and []const u8" {...@@ -246,7 +257,7 @@ test "peer type resolution: [0]u8 and []const u8" {
246}257}
247fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 {258fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 {
248 if (a) {259 if (a) {
249 return []const u8 {};260 return []const u8{};
250 }261 }
251262
252 return slice[0..1];263 return slice[0..1];
...@@ -261,7 +272,6 @@ fn castToMaybeSlice() ?[]const u8 {...@@ -261,7 +272,6 @@ fn castToMaybeSlice() ?[]const u8 {
261 return "hi";272 return "hi";
262}273}
263274
264
265test "implicitly cast from [0]T to error![]T" {275test "implicitly cast from [0]T to error![]T" {
266 testCastZeroArrayToErrSliceMut();276 testCastZeroArrayToErrSliceMut();
267 comptime testCastZeroArrayToErrSliceMut();277 comptime testCastZeroArrayToErrSliceMut();
...@@ -329,7 +339,6 @@ fn foo(args: ...) void {...@@ -329,7 +339,6 @@ fn foo(args: ...) void {
329 assert(@typeOf(args[0]) == &const [5]u8);339 assert(@typeOf(args[0]) == &const [5]u8);
330}340}
331341
332
333test "peer type resolution: error and [N]T" {342test "peer type resolution: error and [N]T" {
334 // TODO: implicit error!T to error!U where T can implicitly cast to U343 // TODO: implicit error!T to error!U where T can implicitly cast to U
335 //assert(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));344 //assert(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));
...@@ -378,7 +387,12 @@ fn cast128Float(x: u128) f128 {...@@ -378,7 +387,12 @@ fn cast128Float(x: u128) f128 {
378}387}
379388
380test "const slice widen cast" {389test "const slice widen cast" {
381 const bytes align(4) = []u8{0x12, 0x12, 0x12, 0x12};390 const bytes align(4) = []u8 {
391 0x12,
392 0x12,
393 0x12,
394 0x12,
395 };
382396
383 const u32_value = ([]const u32)(bytes[0..])[0];397 const u32_value = ([]const u32)(bytes[0..])[0];
384 assert(u32_value == 0x12121212);398 assert(u32_value == 0x12121212);
test/cases/coroutines.zig+9-9
...@@ -36,7 +36,7 @@ async fn testAsyncSeq() void {...@@ -36,7 +36,7 @@ async fn testAsyncSeq() void {
36 suspend;36 suspend;
37 seq('d');37 seq('d');
38}38}
39var points = []u8{0} ** "abcdefg".len;39var points = []u8 {0} ** "abcdefg".len;
40var index: usize = 0;40var index: usize = 0;
4141
42fn seq(c: u8) void {42fn seq(c: u8) void {
...@@ -94,7 +94,7 @@ async fn await_another() i32 {...@@ -94,7 +94,7 @@ async fn await_another() i32 {
94 return 1234;94 return 1234;
95}95}
9696
97var await_points = []u8{0} ** "abcdefghi".len;97var await_points = []u8 {0} ** "abcdefghi".len;
98var await_seq_index: usize = 0;98var await_seq_index: usize = 0;
9999
100fn await_seq(c: u8) void {100fn await_seq(c: u8) void {
...@@ -102,7 +102,6 @@ fn await_seq(c: u8) void {...@@ -102,7 +102,6 @@ fn await_seq(c: u8) void {
102 await_seq_index += 1;102 await_seq_index += 1;
103}103}
104104
105
106var early_final_result: i32 = 0;105var early_final_result: i32 = 0;
107106
108test "coroutine await early return" {107test "coroutine await early return" {
...@@ -126,7 +125,7 @@ async fn early_another() i32 {...@@ -126,7 +125,7 @@ async fn early_another() i32 {
126 return 1234;125 return 1234;
127}126}
128127
129var early_points = []u8{0} ** "abcdef".len;128var early_points = []u8 {0} ** "abcdef".len;
130var early_seq_index: usize = 0;129var early_seq_index: usize = 0;
131130
132fn early_seq(c: u8) void {131fn early_seq(c: u8) void {
...@@ -175,8 +174,8 @@ test "async fn pointer in a struct field" {...@@ -175,8 +174,8 @@ test "async fn pointer in a struct field" {
175}174}
176175
177async<&std.mem.Allocator> fn simpleAsyncFn2(y: &i32) void {176async<&std.mem.Allocator> fn simpleAsyncFn2(y: &i32) void {
178 defer *y += 2;177 defer y.* += 2;
179 *y += 1;178 y.* += 1;
180 suspend;179 suspend;
181}180}
182181
...@@ -205,7 +204,8 @@ test "error return trace across suspend points - async return" {...@@ -205,7 +204,8 @@ test "error return trace across suspend points - async return" {
205 cancel p2;204 cancel p2;
206}205}
207206
208fn nonFailing() promise->error!void {207// TODO https://github.com/zig-lang/zig/issues/760
208fn nonFailing() (promise->error!void) {
209 return async<std.debug.global_allocator> suspendThenFail() catch unreachable;209 return async<std.debug.global_allocator> suspendThenFail() catch unreachable;
210}210}
211211
...@@ -238,7 +238,7 @@ async fn testBreakFromSuspend(my_result: &i32) void {...@@ -238,7 +238,7 @@ async fn testBreakFromSuspend(my_result: &i32) void {
238 s: suspend |p| {238 s: suspend |p| {
239 break :s;239 break :s;
240 }240 }
241 *my_result += 1;241 my_result.* += 1;
242 suspend;242 suspend;
243 *my_result += 1;243 my_result.* += 1;
244}244}
test/cases/defer.zig+12-3
...@@ -5,9 +5,18 @@ var index: usize = undefined;...@@ -5,9 +5,18 @@ var index: usize = undefined;
55
6fn runSomeErrorDefers(x: bool) !bool {6fn runSomeErrorDefers(x: bool) !bool {
7 index = 0;7 index = 0;
8 defer {result[index] = 'a'; index += 1;}8 defer {
9 errdefer {result[index] = 'b'; index += 1;}9 result[index] = 'a';
10 defer {result[index] = 'c'; index += 1;}10 index += 1;
11 }
12 errdefer {
13 result[index] = 'b';
14 index += 1;
15 }
16 defer {
17 result[index] = 'c';
18 index += 1;
19 }
11 return if (x) x else error.FalseNotAllowed;20 return if (x) x else error.FalseNotAllowed;
12}21}
1322
test/cases/enum.zig+548-58
...@@ -2,8 +2,15 @@ const assert = @import("std").debug.assert;...@@ -2,8 +2,15 @@ const assert = @import("std").debug.assert;
2const mem = @import("std").mem;2const mem = @import("std").mem;
33
4test "enum type" {4test "enum type" {
5 const foo1 = Foo{ .One = 13};5 const foo1 = Foo {
6 const foo2 = Foo{. Two = Point { .x = 1234, .y = 5678, }};6 .One = 13,
7 };
8 const foo2 = Foo {
9 .Two = Point {
10 .x = 1234,
11 .y = 5678,
12 },
13 };
7 const bar = Bar.B;14 const bar = Bar.B;
815
9 assert(bar == Bar.B);16 assert(bar == Bar.B);
...@@ -41,26 +48,31 @@ const Bar = enum {...@@ -41,26 +48,31 @@ const Bar = enum {
41};48};
4249
43fn returnAnInt(x: i32) Foo {50fn returnAnInt(x: i32) Foo {
44 return Foo { .One = x };51 return Foo {
52 .One = x,
53 };
45}54}
4655
47
48test "constant enum with payload" {56test "constant enum with payload" {
49 var empty = AnEnumWithPayload {.Empty = {}};57 var empty = AnEnumWithPayload {
50 var full = AnEnumWithPayload {.Full = 13};58 .Empty = {},
59 };
60 var full = AnEnumWithPayload {
61 .Full = 13,
62 };
51 shouldBeEmpty(empty);63 shouldBeEmpty(empty);
52 shouldBeNotEmpty(full);64 shouldBeNotEmpty(full);
53}65}
5466
55fn shouldBeEmpty(x: &const AnEnumWithPayload) void {67fn shouldBeEmpty(x: &const AnEnumWithPayload) void {
56 switch (*x) {68 switch (x.*) {
57 AnEnumWithPayload.Empty => {},69 AnEnumWithPayload.Empty => {},
58 else => unreachable,70 else => unreachable,
59 }71 }
60}72}
6173
62fn shouldBeNotEmpty(x: &const AnEnumWithPayload) void {74fn shouldBeNotEmpty(x: &const AnEnumWithPayload) void {
63 switch (*x) {75 switch (x.*) {
64 AnEnumWithPayload.Empty => unreachable,76 AnEnumWithPayload.Empty => unreachable,
65 else => {},77 else => {},
66 }78 }
...@@ -71,8 +83,6 @@ const AnEnumWithPayload = union(enum) {...@@ -71,8 +83,6 @@ const AnEnumWithPayload = union(enum) {
71 Full: i32,83 Full: i32,
72};84};
7385
74
75
76const Number = enum {86const Number = enum {
77 Zero,87 Zero,
78 One,88 One,
...@@ -93,7 +103,6 @@ fn shouldEqual(n: Number, expected: u3) void {...@@ -93,7 +103,6 @@ fn shouldEqual(n: Number, expected: u3) void {
93 assert(u3(n) == expected);103 assert(u3(n) == expected);
94}104}
95105
96
97test "int to enum" {106test "int to enum" {
98 testIntToEnumEval(3);107 testIntToEnumEval(3);
99}108}
...@@ -108,7 +117,6 @@ const IntToEnumNumber = enum {...@@ -108,7 +117,6 @@ const IntToEnumNumber = enum {
108 Four,117 Four,
109};118};
110119
111
112test "@tagName" {120test "@tagName" {
113 assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));121 assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));
114 comptime assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));122 comptime assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));
...@@ -124,7 +132,6 @@ const BareNumber = enum {...@@ -124,7 +132,6 @@ const BareNumber = enum {
124 Three,132 Three,
125};133};
126134
127
128test "enum alignment" {135test "enum alignment" {
129 comptime {136 comptime {
130 assert(@alignOf(AlignTestEnum) >= @alignOf([9]u8));137 assert(@alignOf(AlignTestEnum) >= @alignOf([9]u8));
...@@ -137,47 +144,529 @@ const AlignTestEnum = union(enum) {...@@ -137,47 +144,529 @@ const AlignTestEnum = union(enum) {
137 B: u64,144 B: u64,
138};145};
139146
140const ValueCount1 = enum { I0 };147const ValueCount1 = enum {
141const ValueCount2 = enum { I0, I1 };148 I0,
149};
150const ValueCount2 = enum {
151 I0,
152 I1,
153};
142const ValueCount256 = enum {154const ValueCount256 = enum {
143 I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15,155 I0,
144 I16, I17, I18, I19, I20, I21, I22, I23, I24, I25, I26, I27, I28, I29, I30, I31,156 I1,
145 I32, I33, I34, I35, I36, I37, I38, I39, I40, I41, I42, I43, I44, I45, I46, I47,157 I2,
146 I48, I49, I50, I51, I52, I53, I54, I55, I56, I57, I58, I59, I60, I61, I62, I63,158 I3,
147 I64, I65, I66, I67, I68, I69, I70, I71, I72, I73, I74, I75, I76, I77, I78, I79,159 I4,
148 I80, I81, I82, I83, I84, I85, I86, I87, I88, I89, I90, I91, I92, I93, I94, I95,160 I5,
149 I96, I97, I98, I99, I100, I101, I102, I103, I104, I105, I106, I107, I108, I109,161 I6,
150 I110, I111, I112, I113, I114, I115, I116, I117, I118, I119, I120, I121, I122, I123,162 I7,
151 I124, I125, I126, I127, I128, I129, I130, I131, I132, I133, I134, I135, I136, I137,163 I8,
152 I138, I139, I140, I141, I142, I143, I144, I145, I146, I147, I148, I149, I150, I151,164 I9,
153 I152, I153, I154, I155, I156, I157, I158, I159, I160, I161, I162, I163, I164, I165,165 I10,
154 I166, I167, I168, I169, I170, I171, I172, I173, I174, I175, I176, I177, I178, I179,166 I11,
155 I180, I181, I182, I183, I184, I185, I186, I187, I188, I189, I190, I191, I192, I193,167 I12,
156 I194, I195, I196, I197, I198, I199, I200, I201, I202, I203, I204, I205, I206, I207,168 I13,
157 I208, I209, I210, I211, I212, I213, I214, I215, I216, I217, I218, I219, I220, I221,169 I14,
158 I222, I223, I224, I225, I226, I227, I228, I229, I230, I231, I232, I233, I234, I235,170 I15,
159 I236, I237, I238, I239, I240, I241, I242, I243, I244, I245, I246, I247, I248, I249,171 I16,
160 I250, I251, I252, I253, I254, I255172 I17,
173 I18,
174 I19,
175 I20,
176 I21,
177 I22,
178 I23,
179 I24,
180 I25,
181 I26,
182 I27,
183 I28,
184 I29,
185 I30,
186 I31,
187 I32,
188 I33,
189 I34,
190 I35,
191 I36,
192 I37,
193 I38,
194 I39,
195 I40,
196 I41,
197 I42,
198 I43,
199 I44,
200 I45,
201 I46,
202 I47,
203 I48,
204 I49,
205 I50,
206 I51,
207 I52,
208 I53,
209 I54,
210 I55,
211 I56,
212 I57,
213 I58,
214 I59,
215 I60,
216 I61,
217 I62,
218 I63,
219 I64,
220 I65,
221 I66,
222 I67,
223 I68,
224 I69,
225 I70,
226 I71,
227 I72,
228 I73,
229 I74,
230 I75,
231 I76,
232 I77,
233 I78,
234 I79,
235 I80,
236 I81,
237 I82,
238 I83,
239 I84,
240 I85,
241 I86,
242 I87,
243 I88,
244 I89,
245 I90,
246 I91,
247 I92,
248 I93,
249 I94,
250 I95,
251 I96,
252 I97,
253 I98,
254 I99,
255 I100,
256 I101,
257 I102,
258 I103,
259 I104,
260 I105,
261 I106,
262 I107,
263 I108,
264 I109,
265 I110,
266 I111,
267 I112,
268 I113,
269 I114,
270 I115,
271 I116,
272 I117,
273 I118,
274 I119,
275 I120,
276 I121,
277 I122,
278 I123,
279 I124,
280 I125,
281 I126,
282 I127,
283 I128,
284 I129,
285 I130,
286 I131,
287 I132,
288 I133,
289 I134,
290 I135,
291 I136,
292 I137,
293 I138,
294 I139,
295 I140,
296 I141,
297 I142,
298 I143,
299 I144,
300 I145,
301 I146,
302 I147,
303 I148,
304 I149,
305 I150,
306 I151,
307 I152,
308 I153,
309 I154,
310 I155,
311 I156,
312 I157,
313 I158,
314 I159,
315 I160,
316 I161,
317 I162,
318 I163,
319 I164,
320 I165,
321 I166,
322 I167,
323 I168,
324 I169,
325 I170,
326 I171,
327 I172,
328 I173,
329 I174,
330 I175,
331 I176,
332 I177,
333 I178,
334 I179,
335 I180,
336 I181,
337 I182,
338 I183,
339 I184,
340 I185,
341 I186,
342 I187,
343 I188,
344 I189,
345 I190,
346 I191,
347 I192,
348 I193,
349 I194,
350 I195,
351 I196,
352 I197,
353 I198,
354 I199,
355 I200,
356 I201,
357 I202,
358 I203,
359 I204,
360 I205,
361 I206,
362 I207,
363 I208,
364 I209,
365 I210,
366 I211,
367 I212,
368 I213,
369 I214,
370 I215,
371 I216,
372 I217,
373 I218,
374 I219,
375 I220,
376 I221,
377 I222,
378 I223,
379 I224,
380 I225,
381 I226,
382 I227,
383 I228,
384 I229,
385 I230,
386 I231,
387 I232,
388 I233,
389 I234,
390 I235,
391 I236,
392 I237,
393 I238,
394 I239,
395 I240,
396 I241,
397 I242,
398 I243,
399 I244,
400 I245,
401 I246,
402 I247,
403 I248,
404 I249,
405 I250,
406 I251,
407 I252,
408 I253,
409 I254,
410 I255,
161};411};
162const ValueCount257 = enum {412const ValueCount257 = enum {
163 I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15,413 I0,
164 I16, I17, I18, I19, I20, I21, I22, I23, I24, I25, I26, I27, I28, I29, I30, I31,414 I1,
165 I32, I33, I34, I35, I36, I37, I38, I39, I40, I41, I42, I43, I44, I45, I46, I47,415 I2,
166 I48, I49, I50, I51, I52, I53, I54, I55, I56, I57, I58, I59, I60, I61, I62, I63,416 I3,
167 I64, I65, I66, I67, I68, I69, I70, I71, I72, I73, I74, I75, I76, I77, I78, I79,417 I4,
168 I80, I81, I82, I83, I84, I85, I86, I87, I88, I89, I90, I91, I92, I93, I94, I95,418 I5,
169 I96, I97, I98, I99, I100, I101, I102, I103, I104, I105, I106, I107, I108, I109,419 I6,
170 I110, I111, I112, I113, I114, I115, I116, I117, I118, I119, I120, I121, I122, I123,420 I7,
171 I124, I125, I126, I127, I128, I129, I130, I131, I132, I133, I134, I135, I136, I137,421 I8,
172 I138, I139, I140, I141, I142, I143, I144, I145, I146, I147, I148, I149, I150, I151,422 I9,
173 I152, I153, I154, I155, I156, I157, I158, I159, I160, I161, I162, I163, I164, I165,423 I10,
174 I166, I167, I168, I169, I170, I171, I172, I173, I174, I175, I176, I177, I178, I179,424 I11,
175 I180, I181, I182, I183, I184, I185, I186, I187, I188, I189, I190, I191, I192, I193,425 I12,
176 I194, I195, I196, I197, I198, I199, I200, I201, I202, I203, I204, I205, I206, I207,426 I13,
177 I208, I209, I210, I211, I212, I213, I214, I215, I216, I217, I218, I219, I220, I221,427 I14,
178 I222, I223, I224, I225, I226, I227, I228, I229, I230, I231, I232, I233, I234, I235,428 I15,
179 I236, I237, I238, I239, I240, I241, I242, I243, I244, I245, I246, I247, I248, I249,429 I16,
180 I250, I251, I252, I253, I254, I255, I256430 I17,
431 I18,
432 I19,
433 I20,
434 I21,
435 I22,
436 I23,
437 I24,
438 I25,
439 I26,
440 I27,
441 I28,
442 I29,
443 I30,
444 I31,
445 I32,
446 I33,
447 I34,
448 I35,
449 I36,
450 I37,
451 I38,
452 I39,
453 I40,
454 I41,
455 I42,
456 I43,
457 I44,
458 I45,
459 I46,
460 I47,
461 I48,
462 I49,
463 I50,
464 I51,
465 I52,
466 I53,
467 I54,
468 I55,
469 I56,
470 I57,
471 I58,
472 I59,
473 I60,
474 I61,
475 I62,
476 I63,
477 I64,
478 I65,
479 I66,
480 I67,
481 I68,
482 I69,
483 I70,
484 I71,
485 I72,
486 I73,
487 I74,
488 I75,
489 I76,
490 I77,
491 I78,
492 I79,
493 I80,
494 I81,
495 I82,
496 I83,
497 I84,
498 I85,
499 I86,
500 I87,
501 I88,
502 I89,
503 I90,
504 I91,
505 I92,
506 I93,
507 I94,
508 I95,
509 I96,
510 I97,
511 I98,
512 I99,
513 I100,
514 I101,
515 I102,
516 I103,
517 I104,
518 I105,
519 I106,
520 I107,
521 I108,
522 I109,
523 I110,
524 I111,
525 I112,
526 I113,
527 I114,
528 I115,
529 I116,
530 I117,
531 I118,
532 I119,
533 I120,
534 I121,
535 I122,
536 I123,
537 I124,
538 I125,
539 I126,
540 I127,
541 I128,
542 I129,
543 I130,
544 I131,
545 I132,
546 I133,
547 I134,
548 I135,
549 I136,
550 I137,
551 I138,
552 I139,
553 I140,
554 I141,
555 I142,
556 I143,
557 I144,
558 I145,
559 I146,
560 I147,
561 I148,
562 I149,
563 I150,
564 I151,
565 I152,
566 I153,
567 I154,
568 I155,
569 I156,
570 I157,
571 I158,
572 I159,
573 I160,
574 I161,
575 I162,
576 I163,
577 I164,
578 I165,
579 I166,
580 I167,
581 I168,
582 I169,
583 I170,
584 I171,
585 I172,
586 I173,
587 I174,
588 I175,
589 I176,
590 I177,
591 I178,
592 I179,
593 I180,
594 I181,
595 I182,
596 I183,
597 I184,
598 I185,
599 I186,
600 I187,
601 I188,
602 I189,
603 I190,
604 I191,
605 I192,
606 I193,
607 I194,
608 I195,
609 I196,
610 I197,
611 I198,
612 I199,
613 I200,
614 I201,
615 I202,
616 I203,
617 I204,
618 I205,
619 I206,
620 I207,
621 I208,
622 I209,
623 I210,
624 I211,
625 I212,
626 I213,
627 I214,
628 I215,
629 I216,
630 I217,
631 I218,
632 I219,
633 I220,
634 I221,
635 I222,
636 I223,
637 I224,
638 I225,
639 I226,
640 I227,
641 I228,
642 I229,
643 I230,
644 I231,
645 I232,
646 I233,
647 I234,
648 I235,
649 I236,
650 I237,
651 I238,
652 I239,
653 I240,
654 I241,
655 I242,
656 I243,
657 I244,
658 I245,
659 I246,
660 I247,
661 I248,
662 I249,
663 I250,
664 I251,
665 I252,
666 I253,
667 I254,
668 I255,
669 I256,
181};670};
182671
183test "enum sizes" {672test "enum sizes" {
...@@ -189,11 +678,11 @@ test "enum sizes" {...@@ -189,11 +678,11 @@ test "enum sizes" {
189 }678 }
190}679}
191680
192const Small2 = enum (u2) {681const Small2 = enum(u2) {
193 One,682 One,
194 Two,683 Two,
195};684};
196const Small = enum (u2) {685const Small = enum(u2) {
197 One,686 One,
198 Two,687 Two,
199 Three,688 Three,
...@@ -213,8 +702,7 @@ test "set enum tag type" {...@@ -213,8 +702,7 @@ test "set enum tag type" {
213 }702 }
214}703}
215704
216705const A = enum(u3) {
217const A = enum (u3) {
218 One,706 One,
219 Two,707 Two,
220 Three,708 Three,
...@@ -225,7 +713,7 @@ const A = enum (u3) {...@@ -225,7 +713,7 @@ const A = enum (u3) {
225 Four2,713 Four2,
226};714};
227715
228const B = enum (u3) {716const B = enum(u3) {
229 One3,717 One3,
230 Two3,718 Two3,
231 Three3,719 Three3,
...@@ -236,7 +724,7 @@ const B = enum (u3) {...@@ -236,7 +724,7 @@ const B = enum (u3) {
236 Four23,724 Four23,
237};725};
238726
239const C = enum (u2) {727const C = enum(u2) {
240 One4,728 One4,
241 Two4,729 Two4,
242 Three4,730 Three4,
...@@ -389,6 +877,8 @@ test "enum with tag values don't require parens" {...@@ -389,6 +877,8 @@ test "enum with tag values don't require parens" {
389}877}
390878
391test "enum with 1 field but explicit tag type should still have the tag type" {879test "enum with 1 field but explicit tag type should still have the tag type" {
392 const Enum = enum(u8) { B = 2 };880 const Enum = enum(u8) {
881 B = 2,
882 };
393 comptime @import("std").debug.assert(@sizeOf(Enum) == @sizeOf(u8));883 comptime @import("std").debug.assert(@sizeOf(Enum) == @sizeOf(u8));
394}884}
test/cases/enum_with_members.zig+7-3
...@@ -7,7 +7,7 @@ const ET = union(enum) {...@@ -7,7 +7,7 @@ const ET = union(enum) {
7 UINT: u32,7 UINT: u32,
88
9 pub fn print(a: &const ET, buf: []u8) error!usize {9 pub fn print(a: &const ET, buf: []u8) error!usize {
10 return switch (*a) {10 return switch (a.*) {
11 ET.SINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0),11 ET.SINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0),
12 ET.UINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0),12 ET.UINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0),
13 };13 };
...@@ -15,8 +15,12 @@ const ET = union(enum) {...@@ -15,8 +15,12 @@ const ET = union(enum) {
15};15};
1616
17test "enum with members" {17test "enum with members" {
18 const a = ET { .SINT = -42 };18 const a = ET {
19 const b = ET { .UINT = 42 };19 .SINT = -42,
20 };
21 const b = ET {
22 .UINT = 42,
23 };
20 var buf: [20]u8 = undefined;24 var buf: [20]u8 = undefined;
2125
22 assert((a.print(buf[0..]) catch unreachable) == 3);26 assert((a.print(buf[0..]) catch unreachable) == 3);
test/cases/error.zig+30-26
...@@ -30,14 +30,12 @@ test "@errorName" {...@@ -30,14 +30,12 @@ test "@errorName" {
30 assert(mem.eql(u8, @errorName(error.ALongerErrorName), "ALongerErrorName"));30 assert(mem.eql(u8, @errorName(error.ALongerErrorName), "ALongerErrorName"));
31}31}
3232
33
34test "error values" {33test "error values" {
35 const a = i32(error.err1);34 const a = i32(error.err1);
36 const b = i32(error.err2);35 const b = i32(error.err2);
37 assert(a != b);36 assert(a != b);
38}37}
3938
40
41test "redefinition of error values allowed" {39test "redefinition of error values allowed" {
42 shouldBeNotEqual(error.AnError, error.SecondError);40 shouldBeNotEqual(error.AnError, error.SecondError);
43}41}
...@@ -45,7 +43,6 @@ fn shouldBeNotEqual(a: error, b: error) void {...@@ -45,7 +43,6 @@ fn shouldBeNotEqual(a: error, b: error) void {
45 if (a == b) unreachable;43 if (a == b) unreachable;
46}44}
4745
48
49test "error binary operator" {46test "error binary operator" {
50 const a = errBinaryOperatorG(true) catch 3;47 const a = errBinaryOperatorG(true) catch 3;
51 const b = errBinaryOperatorG(false) catch 3;48 const b = errBinaryOperatorG(false) catch 3;
...@@ -56,20 +53,20 @@ fn errBinaryOperatorG(x: bool) error!isize {...@@ -56,20 +53,20 @@ fn errBinaryOperatorG(x: bool) error!isize {
56 return if (x) error.ItBroke else isize(10);53 return if (x) error.ItBroke else isize(10);
57}54}
5855
59
60test "unwrap simple value from error" {56test "unwrap simple value from error" {
61 const i = unwrapSimpleValueFromErrorDo() catch unreachable;57 const i = unwrapSimpleValueFromErrorDo() catch unreachable;
62 assert(i == 13);58 assert(i == 13);
63}59}
64fn unwrapSimpleValueFromErrorDo() error!isize { return 13; }60fn unwrapSimpleValueFromErrorDo() error!isize {
6561 return 13;
62}
6663
67test "error return in assignment" {64test "error return in assignment" {
68 doErrReturnInAssignment() catch unreachable;65 doErrReturnInAssignment() catch unreachable;
69}66}
7067
71fn doErrReturnInAssignment() error!void {68fn doErrReturnInAssignment() error!void {
72 var x : i32 = undefined;69 var x: i32 = undefined;
73 x = try makeANonErr();70 x = try makeANonErr();
74}71}
7572
...@@ -95,7 +92,10 @@ test "error set type " {...@@ -95,7 +92,10 @@ test "error set type " {
95 comptime testErrorSetType();92 comptime testErrorSetType();
96}93}
9794
98const MyErrSet = error {OutOfMemory, FileNotFound};95const MyErrSet = error {
96 OutOfMemory,
97 FileNotFound,
98};
9999
100fn testErrorSetType() void {100fn testErrorSetType() void {
101 assert(@memberCount(MyErrSet) == 2);101 assert(@memberCount(MyErrSet) == 2);
...@@ -109,14 +109,19 @@ fn testErrorSetType() void {...@@ -109,14 +109,19 @@ fn testErrorSetType() void {
109 }109 }
110}110}
111111
112
113test "explicit error set cast" {112test "explicit error set cast" {
114 testExplicitErrorSetCast(Set1.A);113 testExplicitErrorSetCast(Set1.A);
115 comptime testExplicitErrorSetCast(Set1.A);114 comptime testExplicitErrorSetCast(Set1.A);
116}115}
117116
118const Set1 = error{A, B};117const Set1 = error {
119const Set2 = error{A, C};118 A,
119 B,
120};
121const Set2 = error {
122 A,
123 C,
124};
120125
121fn testExplicitErrorSetCast(set1: Set1) void {126fn testExplicitErrorSetCast(set1: Set1) void {
122 var x = Set2(set1);127 var x = Set2(set1);
...@@ -129,7 +134,8 @@ test "comptime test error for empty error set" {...@@ -129,7 +134,8 @@ test "comptime test error for empty error set" {
129 comptime testComptimeTestErrorEmptySet(1234);134 comptime testComptimeTestErrorEmptySet(1234);
130}135}
131136
132const EmptyErrorSet = error {};137const EmptyErrorSet = error {
138};
133139
134fn testComptimeTestErrorEmptySet(x: EmptyErrorSet!i32) void {140fn testComptimeTestErrorEmptySet(x: EmptyErrorSet!i32) void {
135 if (x) |v| assert(v == 1234) else |err| @compileError("bad");141 if (x) |v| assert(v == 1234) else |err| @compileError("bad");
...@@ -145,7 +151,9 @@ test "comptime err to int of error set with only 1 possible value" {...@@ -145,7 +151,9 @@ test "comptime err to int of error set with only 1 possible value" {
145 testErrToIntWithOnePossibleValue(error.A, u32(error.A));151 testErrToIntWithOnePossibleValue(error.A, u32(error.A));
146 comptime testErrToIntWithOnePossibleValue(error.A, u32(error.A));152 comptime testErrToIntWithOnePossibleValue(error.A, u32(error.A));
147}153}
148fn testErrToIntWithOnePossibleValue(x: error{A}, comptime value: u32) void {154fn testErrToIntWithOnePossibleValue(x: error {
155 A,
156}, comptime value: u32) void {
149 if (u32(x) != value) {157 if (u32(x) != value) {
150 @compileError("bad");158 @compileError("bad");
151 }159 }
...@@ -176,7 +184,6 @@ fn quux_1() !i32 {...@@ -176,7 +184,6 @@ fn quux_1() !i32 {
176 return error.C;184 return error.C;
177}185}
178186
179
180test "error: fn returning empty error set can be passed as fn returning any error" {187test "error: fn returning empty error set can be passed as fn returning any error" {
181 entry();188 entry();
182 comptime entry();189 comptime entry();
...@@ -186,24 +193,24 @@ fn entry() void {...@@ -186,24 +193,24 @@ fn entry() void {
186 foo2(bar2);193 foo2(bar2);
187}194}
188195
189fn foo2(f: fn()error!void) void {196fn foo2(f: fn() error!void) void {
190 const x = f();197 const x = f();
191}198}
192199
193fn bar2() (error{}!void) { }200fn bar2() (error {
194201}!void) {}
195202
196test "error: Zero sized error set returned with value payload crash" {203test "error: Zero sized error set returned with value payload crash" {
197 _ = foo3(0);204 _ = foo3(0);
198 _ = comptime foo3(0);205 _ = comptime foo3(0);
199}206}
200207
201const Error = error{};208const Error = error {
209};
202fn foo3(b: usize) Error!usize {210fn foo3(b: usize) Error!usize {
203 return b;211 return b;
204}212}
205213
206
207test "error: Infer error set from literals" {214test "error: Infer error set from literals" {
208 _ = nullLiteral("n") catch |err| handleErrors(err);215 _ = nullLiteral("n") catch |err| handleErrors(err);
209 _ = floatLiteral("n") catch |err| handleErrors(err);216 _ = floatLiteral("n") catch |err| handleErrors(err);
...@@ -215,29 +222,26 @@ test "error: Infer error set from literals" {...@@ -215,29 +222,26 @@ test "error: Infer error set from literals" {
215222
216fn handleErrors(err: var) noreturn {223fn handleErrors(err: var) noreturn {
217 switch (err) {224 switch (err) {
218 error.T => {}225 error.T => {},
219 }226 }
220227
221 unreachable;228 unreachable;
222}229}
223230
224fn nullLiteral(str: []const u8) !?i64 {231fn nullLiteral(str: []const u8) !?i64 {
225 if (str[0] == 'n')232 if (str[0] == 'n') return null;
226 return null;
227233
228 return error.T;234 return error.T;
229}235}
230236
231fn floatLiteral(str: []const u8) !?f64 {237fn floatLiteral(str: []const u8) !?f64 {
232 if (str[0] == 'n')238 if (str[0] == 'n') return 1.0;
233 return 1.0;
234239
235 return error.T;240 return error.T;
236}241}
237242
238fn intLiteral(str: []const u8) !?i64 {243fn intLiteral(str: []const u8) !?i64 {
239 if (str[0] == 'n')244 if (str[0] == 'n') return 1;
240 return 1;
241245
242 return error.T;246 return error.T;
243}247}
test/cases/eval.zig+88-55
...@@ -11,8 +11,6 @@ fn fibonacci(x: i32) i32 {...@@ -11,8 +11,6 @@ fn fibonacci(x: i32) i32 {
11 return fibonacci(x - 1) + fibonacci(x - 2);11 return fibonacci(x - 1) + fibonacci(x - 2);
12}12}
1313
14
15
16fn unwrapAndAddOne(blah: ?i32) i32 {14fn unwrapAndAddOne(blah: ?i32) i32 {
17 return ??blah + 1;15 return ??blah + 1;
18}16}
...@@ -40,13 +38,13 @@ test "inline variable gets result of const if" {...@@ -40,13 +38,13 @@ test "inline variable gets result of const if" {
40 assert(gimme1or2(false) == 2);38 assert(gimme1or2(false) == 2);
41}39}
4240
43
44test "static function evaluation" {41test "static function evaluation" {
45 assert(statically_added_number == 3);42 assert(statically_added_number == 3);
46}43}
47const statically_added_number = staticAdd(1, 2);44const statically_added_number = staticAdd(1, 2);
48fn staticAdd(a: i32, b: i32) i32 { return a + b; }45fn staticAdd(a: i32, b: i32) i32 {
4946 return a + b;
47}
5048
51test "const expr eval on single expr blocks" {49test "const expr eval on single expr blocks" {
52 assert(constExprEvalOnSingleExprBlocksFn(1, true) == 3);50 assert(constExprEvalOnSingleExprBlocksFn(1, true) == 3);
...@@ -64,9 +62,6 @@ fn constExprEvalOnSingleExprBlocksFn(x: i32, b: bool) i32 {...@@ -64,9 +62,6 @@ fn constExprEvalOnSingleExprBlocksFn(x: i32, b: bool) i32 {
64 return result;62 return result;
65}63}
6664
67
68
69
70test "statically initialized list" {65test "statically initialized list" {
71 assert(static_point_list[0].x == 1);66 assert(static_point_list[0].x == 1);
72 assert(static_point_list[0].y == 2);67 assert(static_point_list[0].y == 2);
...@@ -77,7 +72,10 @@ const Point = struct {...@@ -77,7 +72,10 @@ const Point = struct {
77 x: i32,72 x: i32,
78 y: i32,73 y: i32,
79};74};
80const static_point_list = []Point { makePoint(1, 2), makePoint(3, 4) };75const static_point_list = []Point {
76 makePoint(1, 2),
77 makePoint(3, 4),
78};
81fn makePoint(x: i32, y: i32) Point {79fn makePoint(x: i32, y: i32) Point {
82 return Point {80 return Point {
83 .x = x,81 .x = x,
...@@ -85,7 +83,6 @@ fn makePoint(x: i32, y: i32) Point {...@@ -85,7 +83,6 @@ fn makePoint(x: i32, y: i32) Point {
85 };83 };
86}84}
8785
88
89test "static eval list init" {86test "static eval list init" {
90 assert(static_vec3.data[2] == 1.0);87 assert(static_vec3.data[2] == 1.0);
91 assert(vec3(0.0, 0.0, 3.0).data[2] == 3.0);88 assert(vec3(0.0, 0.0, 3.0).data[2] == 3.0);
...@@ -96,17 +93,19 @@ pub const Vec3 = struct {...@@ -96,17 +93,19 @@ pub const Vec3 = struct {
96};93};
97pub fn vec3(x: f32, y: f32, z: f32) Vec3 {94pub fn vec3(x: f32, y: f32, z: f32) Vec3 {
98 return Vec3 {95 return Vec3 {
99 .data = []f32 { x, y, z, },96 .data = []f32 {
97 x,
98 y,
99 z,
100 },
100 };101 };
101}102}
102103
103
104test "constant expressions" {104test "constant expressions" {
105 var array : [array_size]u8 = undefined;105 var array: [array_size]u8 = undefined;
106 assert(@sizeOf(@typeOf(array)) == 20);106 assert(@sizeOf(@typeOf(array)) == 20);
107}107}
108const array_size : u8 = 20;108const array_size: u8 = 20;
109
110109
111test "constant struct with negation" {110test "constant struct with negation" {
112 assert(vertices[0].x == -0.6);111 assert(vertices[0].x == -0.6);
...@@ -119,12 +118,29 @@ const Vertex = struct {...@@ -119,12 +118,29 @@ const Vertex = struct {
119 b: f32,118 b: f32,
120};119};
121const vertices = []Vertex {120const vertices = []Vertex {
122 Vertex { .x = -0.6, .y = -0.4, .r = 1.0, .g = 0.0, .b = 0.0 },121 Vertex {
123 Vertex { .x = 0.6, .y = -0.4, .r = 0.0, .g = 1.0, .b = 0.0 },122 .x = -0.6,
124 Vertex { .x = 0.0, .y = 0.6, .r = 0.0, .g = 0.0, .b = 1.0 },123 .y = -0.4,
124 .r = 1.0,
125 .g = 0.0,
126 .b = 0.0,
127 },
128 Vertex {
129 .x = 0.6,
130 .y = -0.4,
131 .r = 0.0,
132 .g = 1.0,
133 .b = 0.0,
134 },
135 Vertex {
136 .x = 0.0,
137 .y = 0.6,
138 .r = 0.0,
139 .g = 0.0,
140 .b = 1.0,
141 },
125};142};
126143
127
128test "statically initialized struct" {144test "statically initialized struct" {
129 st_init_str_foo.x += 1;145 st_init_str_foo.x += 1;
130 assert(st_init_str_foo.x == 14);146 assert(st_init_str_foo.x == 14);
...@@ -133,15 +149,21 @@ const StInitStrFoo = struct {...@@ -133,15 +149,21 @@ const StInitStrFoo = struct {
133 x: i32,149 x: i32,
134 y: bool,150 y: bool,
135};151};
136var st_init_str_foo = StInitStrFoo { .x = 13, .y = true, };152var st_init_str_foo = StInitStrFoo {
137153 .x = 13,
154 .y = true,
155};
138156
139test "statically initalized array literal" {157test "statically initalized array literal" {
140 const y : [4]u8 = st_init_arr_lit_x;158 const y: [4]u8 = st_init_arr_lit_x;
141 assert(y[3] == 4);159 assert(y[3] == 4);
142}160}
143const st_init_arr_lit_x = []u8{1,2,3,4};161const st_init_arr_lit_x = []u8 {
144162 1,
163 2,
164 3,
165 4,
166};
145167
146test "const slice" {168test "const slice" {
147 comptime {169 comptime {
...@@ -198,14 +220,29 @@ const CmdFn = struct {...@@ -198,14 +220,29 @@ const CmdFn = struct {
198 func: fn(i32) i32,220 func: fn(i32) i32,
199};221};
200222
201const cmd_fns = []CmdFn{223const cmd_fns = []CmdFn {
202 CmdFn {.name = "one", .func = one},224 CmdFn {
203 CmdFn {.name = "two", .func = two},225 .name = "one",
204 CmdFn {.name = "three", .func = three},226 .func = one,
227 },
228 CmdFn {
229 .name = "two",
230 .func = two,
231 },
232 CmdFn {
233 .name = "three",
234 .func = three,
235 },
205};236};
206fn one(value: i32) i32 { return value + 1; }237fn one(value: i32) i32 {
207fn two(value: i32) i32 { return value + 2; }238 return value + 1;
208fn three(value: i32) i32 { return value + 3; }239}
240fn two(value: i32) i32 {
241 return value + 2;
242}
243fn three(value: i32) i32 {
244 return value + 3;
245}
209246
210fn performFn(comptime prefix_char: u8, start_value: i32) i32 {247fn performFn(comptime prefix_char: u8, start_value: i32) i32 {
211 var result: i32 = start_value;248 var result: i32 = start_value;
...@@ -229,7 +266,7 @@ test "eval @setRuntimeSafety at compile-time" {...@@ -229,7 +266,7 @@ test "eval @setRuntimeSafety at compile-time" {
229 assert(result == 1234);266 assert(result == 1234);
230}267}
231268
232fn fnWithSetRuntimeSafety() i32{269fn fnWithSetRuntimeSafety() i32 {
233 @setRuntimeSafety(true);270 @setRuntimeSafety(true);
234 return 1234;271 return 1234;
235}272}
...@@ -244,7 +281,6 @@ fn fnWithFloatMode() f32 {...@@ -244,7 +281,6 @@ fn fnWithFloatMode() f32 {
244 return 1234.0;281 return 1234.0;
245}282}
246283
247
248const SimpleStruct = struct {284const SimpleStruct = struct {
249 field: i32,285 field: i32,
250286
...@@ -253,7 +289,9 @@ const SimpleStruct = struct {...@@ -253,7 +289,9 @@ const SimpleStruct = struct {
253 }289 }
254};290};
255291
256var simple_struct = SimpleStruct{ .field = 1234, };292var simple_struct = SimpleStruct {
293 .field = 1234,
294};
257295
258const bound_fn = simple_struct.method;296const bound_fn = simple_struct.method;
259297
...@@ -261,8 +299,6 @@ test "call method on bound fn referring to var instance" {...@@ -261,8 +299,6 @@ test "call method on bound fn referring to var instance" {
261 assert(bound_fn() == 1237);299 assert(bound_fn() == 1237);
262}300}
263301
264
265
266test "ptr to local array argument at comptime" {302test "ptr to local array argument at comptime" {
267 comptime {303 comptime {
268 var bytes: [10]u8 = undefined;304 var bytes: [10]u8 = undefined;
...@@ -277,7 +313,6 @@ fn modifySomeBytes(bytes: []u8) void {...@@ -277,7 +313,6 @@ fn modifySomeBytes(bytes: []u8) void {
277 bytes[9] = 'b';313 bytes[9] = 'b';
278}314}
279315
280
281test "comparisons 0 <= uint and 0 > uint should be comptime" {316test "comparisons 0 <= uint and 0 > uint should be comptime" {
282 testCompTimeUIntComparisons(1234);317 testCompTimeUIntComparisons(1234);
283}318}
...@@ -296,8 +331,6 @@ fn testCompTimeUIntComparisons(x: u32) void {...@@ -296,8 +331,6 @@ fn testCompTimeUIntComparisons(x: u32) void {
296 }331 }
297}332}
298333
299
300
301test "const ptr to variable data changes at runtime" {334test "const ptr to variable data changes at runtime" {
302 assert(foo_ref.name[0] == 'a');335 assert(foo_ref.name[0] == 'a');
303 foo_ref.name = "b";336 foo_ref.name = "b";
...@@ -308,11 +341,11 @@ const Foo = struct {...@@ -308,11 +341,11 @@ const Foo = struct {
308 name: []const u8,341 name: []const u8,
309};342};
310343
311var foo_contents = Foo { .name = "a", };344var foo_contents = Foo {
345 .name = "a",
346};
312const foo_ref = &foo_contents;347const foo_ref = &foo_contents;
313348
314
315
316test "create global array with for loop" {349test "create global array with for loop" {
317 assert(global_array[5] == 5 * 5);350 assert(global_array[5] == 5 * 5);
318 assert(global_array[9] == 9 * 9);351 assert(global_array[9] == 9 * 9);
...@@ -321,7 +354,7 @@ test "create global array with for loop" {...@@ -321,7 +354,7 @@ test "create global array with for loop" {
321const global_array = x: {354const global_array = x: {
322 var result: [10]usize = undefined;355 var result: [10]usize = undefined;
323 for (result) |*item, index| {356 for (result) |*item, index| {
324 *item = index * index;357 item.* = index * index;
325 }358 }
326 break :x result;359 break :x result;
327};360};
...@@ -379,7 +412,7 @@ test "f128 at compile time is lossy" {...@@ -379,7 +412,7 @@ test "f128 at compile time is lossy" {
379412
380pub fn TypeWithCompTimeSlice(comptime field_name: []const u8) type {413pub fn TypeWithCompTimeSlice(comptime field_name: []const u8) type {
381 return struct {414 return struct {
382 pub const Node = struct { };415 pub const Node = struct {};
383 };416 };
384}417}
385418
...@@ -401,10 +434,10 @@ fn copyWithPartialInline(s: []u32, b: []u8) void {...@@ -401,10 +434,10 @@ fn copyWithPartialInline(s: []u32, b: []u8) void {
401 comptime var i: usize = 0;434 comptime var i: usize = 0;
402 inline while (i < 4) : (i += 1) {435 inline while (i < 4) : (i += 1) {
403 s[i] = 0;436 s[i] = 0;
404 s[i] |= u32(b[i*4+0]) << 24;437 s[i] |= u32(b[i * 4 + 0]) << 24;
405 s[i] |= u32(b[i*4+1]) << 16;438 s[i] |= u32(b[i * 4 + 1]) << 16;
406 s[i] |= u32(b[i*4+2]) << 8;439 s[i] |= u32(b[i * 4 + 2]) << 8;
407 s[i] |= u32(b[i*4+3]) << 0;440 s[i] |= u32(b[i * 4 + 3]) << 0;
408 }441 }
409}442}
410443
...@@ -413,7 +446,7 @@ test "binary math operator in partially inlined function" {...@@ -413,7 +446,7 @@ test "binary math operator in partially inlined function" {
413 var b: [16]u8 = undefined;446 var b: [16]u8 = undefined;
414447
415 for (b) |*r, i|448 for (b) |*r, i|
416 *r = u8(i + 1);449 r.* = u8(i + 1);
417450
418 copyWithPartialInline(s[0..], b[0..]);451 copyWithPartialInline(s[0..], b[0..]);
419 assert(s[0] == 0x1020304);452 assert(s[0] == 0x1020304);
...@@ -422,7 +455,6 @@ test "binary math operator in partially inlined function" {...@@ -422,7 +455,6 @@ test "binary math operator in partially inlined function" {
422 assert(s[3] == 0xd0e0f10);455 assert(s[3] == 0xd0e0f10);
423}456}
424457
425
426test "comptime function with the same args is memoized" {458test "comptime function with the same args is memoized" {
427 comptime {459 comptime {
428 assert(MakeType(i32) == MakeType(i32));460 assert(MakeType(i32) == MakeType(i32));
...@@ -447,12 +479,12 @@ test "comptime function with mutable pointer is not memoized" {...@@ -447,12 +479,12 @@ test "comptime function with mutable pointer is not memoized" {
447}479}
448480
449fn increment(value: &i32) void {481fn increment(value: &i32) void {
450 *value += 1;482 value.* += 1;
451}483}
452484
453fn generateTable(comptime T: type) [1010]T {485fn generateTable(comptime T: type) [1010]T {
454 var res : [1010]T = undefined;486 var res: [1010]T = undefined;
455 var i : usize = 0;487 var i: usize = 0;
456 while (i < 1010) : (i += 1) {488 while (i < 1010) : (i += 1) {
457 res[i] = T(i);489 res[i] = T(i);
458 }490 }
...@@ -496,9 +528,10 @@ const SingleFieldStruct = struct {...@@ -496,9 +528,10 @@ const SingleFieldStruct = struct {
496 }528 }
497};529};
498test "const ptr to comptime mutable data is not memoized" {530test "const ptr to comptime mutable data is not memoized" {
499
500 comptime {531 comptime {
501 var foo = SingleFieldStruct {.x = 1};532 var foo = SingleFieldStruct {
533 .x = 1,
534 };
502 assert(foo.read_x() == 1);535 assert(foo.read_x() == 1);
503 foo.x = 2;536 foo.x = 2;
504 assert(foo.read_x() == 2);537 assert(foo.read_x() == 2);
test/cases/fn.zig+26-18
...@@ -7,7 +7,6 @@ fn testParamsAdd(a: i32, b: i32) i32 {...@@ -7,7 +7,6 @@ fn testParamsAdd(a: i32, b: i32) i32 {
7 return a + b;7 return a + b;
8}8}
99
10
11test "local variables" {10test "local variables" {
12 testLocVars(2);11 testLocVars(2);
13}12}
...@@ -16,7 +15,6 @@ fn testLocVars(b: i32) void {...@@ -16,7 +15,6 @@ fn testLocVars(b: i32) void {
16 if (a + b != 3) unreachable;15 if (a + b != 3) unreachable;
17}16}
1817
19
20test "void parameters" {18test "void parameters" {
21 voidFun(1, void{}, 2, {});19 voidFun(1, void{}, 2, {});
22}20}
...@@ -27,9 +25,8 @@ fn voidFun(a: i32, b: void, c: i32, d: void) void {...@@ -27,9 +25,8 @@ fn voidFun(a: i32, b: void, c: i32, d: void) void {
27 return vv;25 return vv;
28}26}
2927
30
31test "mutable local variables" {28test "mutable local variables" {
32 var zero : i32 = 0;29 var zero: i32 = 0;
33 assert(zero == 0);30 assert(zero == 0);
3431
35 var i = i32(0);32 var i = i32(0);
...@@ -41,7 +38,7 @@ test "mutable local variables" {...@@ -41,7 +38,7 @@ test "mutable local variables" {
4138
42test "separate block scopes" {39test "separate block scopes" {
43 {40 {
44 const no_conflict : i32 = 5;41 const no_conflict: i32 = 5;
45 assert(no_conflict == 5);42 assert(no_conflict == 5);
46 }43 }
4744
...@@ -56,8 +53,7 @@ test "call function with empty string" {...@@ -56,8 +53,7 @@ test "call function with empty string" {
56 acceptsString("");53 acceptsString("");
57}54}
5855
59fn acceptsString(foo: []u8) void { }56fn acceptsString(foo: []u8) void {}
60
6157
62fn @"weird function name"() i32 {58fn @"weird function name"() i32 {
63 return 1234;59 return 1234;
...@@ -70,31 +66,43 @@ test "implicit cast function unreachable return" {...@@ -70,31 +66,43 @@ test "implicit cast function unreachable return" {
70 wantsFnWithVoid(fnWithUnreachable);66 wantsFnWithVoid(fnWithUnreachable);
71}67}
7268
73fn wantsFnWithVoid(f: fn() void) void { }69fn wantsFnWithVoid(f: fn() void) void {}
7470
75fn fnWithUnreachable() noreturn {71fn fnWithUnreachable() noreturn {
76 unreachable;72 unreachable;
77}73}
7874
79
80test "function pointers" {75test "function pointers" {
81 const fns = []@typeOf(fn1) { fn1, fn2, fn3, fn4, };76 const fns = []@typeOf(fn1) {
77 fn1,
78 fn2,
79 fn3,
80 fn4,
81 };
82 for (fns) |f, i| {82 for (fns) |f, i| {
83 assert(f() == u32(i) + 5);83 assert(f() == u32(i) + 5);
84 }84 }
85}85}
86fn fn1() u32 {return 5;}86fn fn1() u32 {
87fn fn2() u32 {return 6;}87 return 5;
88fn fn3() u32 {return 7;}88}
89fn fn4() u32 {return 8;}89fn fn2() u32 {
9090 return 6;
91}
92fn fn3() u32 {
93 return 7;
94}
95fn fn4() u32 {
96 return 8;
97}
9198
92test "inline function call" {99test "inline function call" {
93 assert(@inlineCall(add, 3, 9) == 12);100 assert(@inlineCall(add, 3, 9) == 12);
94}101}
95102
96fn add(a: i32, b: i32) i32 { return a + b; }103fn add(a: i32, b: i32) i32 {
97104 return a + b;
105}
98106
99test "number literal as an argument" {107test "number literal as an argument" {
100 numberLiteralArg(3);108 numberLiteralArg(3);
...@@ -110,4 +118,4 @@ test "assign inline fn to const variable" {...@@ -110,4 +118,4 @@ test "assign inline fn to const variable" {
110 a();118 a();
111}119}
112120
113inline fn inlineFn() void { }121inline fn inlineFn() void {}
test/cases/for.zig+37-7
...@@ -3,8 +3,14 @@ const assert = std.debug.assert;...@@ -3,8 +3,14 @@ const assert = std.debug.assert;
3const mem = std.mem;3const mem = std.mem;
44
5test "continue in for loop" {5test "continue in for loop" {
6 const array = []i32 {1, 2, 3, 4, 5};6 const array = []i32 {
7 var sum : i32 = 0;7 1,
8 2,
9 3,
10 4,
11 5,
12 };
13 var sum: i32 = 0;
8 for (array) |x| {14 for (array) |x| {
9 sum += x;15 sum += x;
10 if (x < 3) {16 if (x < 3) {
...@@ -24,17 +30,39 @@ test "for loop with pointer elem var" {...@@ -24,17 +30,39 @@ test "for loop with pointer elem var" {
24}30}
25fn mangleString(s: []u8) void {31fn mangleString(s: []u8) void {
26 for (s) |*c| {32 for (s) |*c| {
27 *c += 1;33 c.* += 1;
28 }34 }
29}35}
3036
31test "basic for loop" {37test "basic for loop" {
32 const expected_result = []u8{9, 8, 7, 6, 0, 1, 2, 3, 9, 8, 7, 6, 0, 1, 2, 3 };38 const expected_result = []u8 {
39 9,
40 8,
41 7,
42 6,
43 0,
44 1,
45 2,
46 3,
47 9,
48 8,
49 7,
50 6,
51 0,
52 1,
53 2,
54 3,
55 };
3356
34 var buffer: [expected_result.len]u8 = undefined;57 var buffer: [expected_result.len]u8 = undefined;
35 var buf_index: usize = 0;58 var buf_index: usize = 0;
3659
37 const array = []u8 {9, 8, 7, 6};60 const array = []u8 {
61 9,
62 8,
63 7,
64 6,
65 };
38 for (array) |item| {66 for (array) |item| {
39 buffer[buf_index] = item;67 buffer[buf_index] = item;
40 buf_index += 1;68 buf_index += 1;
...@@ -65,7 +93,8 @@ fn testBreakOuter() void {...@@ -65,7 +93,8 @@ fn testBreakOuter() void {
65 var array = "aoeu";93 var array = "aoeu";
66 var count: usize = 0;94 var count: usize = 0;
67 outer: for (array) |_| {95 outer: for (array) |_| {
68 for (array) |_2| { // TODO shouldn't get error for redeclaring "_"96 // TODO shouldn't get error for redeclaring "_"
97 for (array) |_2| {
69 count += 1;98 count += 1;
70 break :outer;99 break :outer;
71 }100 }
...@@ -82,7 +111,8 @@ fn testContinueOuter() void {...@@ -82,7 +111,8 @@ fn testContinueOuter() void {
82 var array = "aoeu";111 var array = "aoeu";
83 var counter: usize = 0;112 var counter: usize = 0;
84 outer: for (array) |_| {113 outer: for (array) |_| {
85 for (array) |_2| { // TODO shouldn't get error for redeclaring "_"114 // TODO shouldn't get error for redeclaring "_"
115 for (array) |_2| {
86 counter += 1;116 counter += 1;
87 continue :outer;117 continue :outer;
88 }118 }
test/cases/generics.zig+28-14
...@@ -37,7 +37,6 @@ test "fn with comptime args" {...@@ -37,7 +37,6 @@ test "fn with comptime args" {
37 assert(sameButWithFloats(0.43, 0.49) == 0.49);37 assert(sameButWithFloats(0.43, 0.49) == 0.49);
38}38}
3939
40
41test "var params" {40test "var params" {
42 assert(max_i32(12, 34) == 34);41 assert(max_i32(12, 34) == 34);
43 assert(max_f64(1.2, 3.4) == 3.4);42 assert(max_f64(1.2, 3.4) == 3.4);
...@@ -60,7 +59,6 @@ fn max_f64(a: f64, b: f64) f64 {...@@ -60,7 +59,6 @@ fn max_f64(a: f64, b: f64) f64 {
60 return max_var(a, b);59 return max_var(a, b);
61}60}
6261
63
64pub fn List(comptime T: type) type {62pub fn List(comptime T: type) type {
65 return SmallList(T, 8);63 return SmallList(T, 8);
66}64}
...@@ -82,10 +80,15 @@ test "function with return type type" {...@@ -82,10 +80,15 @@ test "function with return type type" {
82 assert(list2.prealloc_items.len == 8);80 assert(list2.prealloc_items.len == 8);
83}81}
8482
85
86test "generic struct" {83test "generic struct" {
87 var a1 = GenNode(i32) {.value = 13, .next = null,};84 var a1 = GenNode(i32) {
88 var b1 = GenNode(bool) {.value = true, .next = null,};85 .value = 13,
86 .next = null,
87 };
88 var b1 = GenNode(bool) {
89 .value = true,
90 .next = null,
91 };
89 assert(a1.value == 13);92 assert(a1.value == 13);
90 assert(a1.value == a1.getVal());93 assert(a1.value == a1.getVal());
91 assert(b1.getVal());94 assert(b1.getVal());
...@@ -94,7 +97,9 @@ fn GenNode(comptime T: type) type {...@@ -94,7 +97,9 @@ fn GenNode(comptime T: type) type {
94 return struct {97 return struct {
95 value: T,98 value: T,
96 next: ?&GenNode(T),99 next: ?&GenNode(T),
97 fn getVal(n: &const GenNode(T)) T { return n.value; }100 fn getVal(n: &const GenNode(T)) T {
101 return n.value;
102 }
98 };103 };
99}104}
100105
...@@ -107,7 +112,6 @@ fn GenericDataThing(comptime count: isize) type {...@@ -107,7 +112,6 @@ fn GenericDataThing(comptime count: isize) type {
107 };112 };
108}113}
109114
110
111test "use generic param in generic param" {115test "use generic param in generic param" {
112 assert(aGenericFn(i32, 3, 4) == 7);116 assert(aGenericFn(i32, 3, 4) == 7);
113}117}
...@@ -115,21 +119,31 @@ fn aGenericFn(comptime T: type, comptime a: T, b: T) T {...@@ -115,21 +119,31 @@ fn aGenericFn(comptime T: type, comptime a: T, b: T) T {
115 return a + b;119 return a + b;
116}120}
117121
118
119test "generic fn with implicit cast" {122test "generic fn with implicit cast" {
120 assert(getFirstByte(u8, []u8 {13}) == 13);123 assert(getFirstByte(u8, []u8 {13}) == 13);
121 assert(getFirstByte(u16, []u16 {0, 13}) == 0);124 assert(getFirstByte(u16, []u16 {
125 0,
126 13,
127 }) == 0);
128}
129fn getByte(ptr: ?&const u8) u8 {
130 return ??ptr.*;
122}131}
123fn getByte(ptr: ?&const u8) u8 {return *??ptr;}
124fn getFirstByte(comptime T: type, mem: []const T) u8 {132fn getFirstByte(comptime T: type, mem: []const T) u8 {
125 return getByte(@ptrCast(&const u8, &mem[0]));133 return getByte(@ptrCast(&const u8, &mem[0]));
126}134}
127135
136const foos = []fn(var) bool {
137 foo1,
138 foo2,
139};
128140
129const foos = []fn(var) bool { foo1, foo2 };141fn foo1(arg: var) bool {
130142 return arg;
131fn foo1(arg: var) bool { return arg; }143}
132fn foo2(arg: var) bool { return !arg; }144fn foo2(arg: var) bool {
145 return !arg;
146}
133147
134test "array of generic fns" {148test "array of generic fns" {
135 assert(foos[0](true));149 assert(foos[0](true));
test/cases/if.zig-1
...@@ -23,7 +23,6 @@ fn firstEqlThird(a: i32, b: i32, c: i32) void {...@@ -23,7 +23,6 @@ fn firstEqlThird(a: i32, b: i32, c: i32) void {
23 }23 }
24}24}
2525
26
27test "else if expression" {26test "else if expression" {
28 assert(elseIfExpressionF(1) == 1);27 assert(elseIfExpressionF(1) == 1);
29}28}
test/cases/import/a_namespace.zig+3-1
...@@ -1 +1,3 @@...@@ -1 +1,3 @@
1pub fn foo() i32 { return 1234; }1pub fn foo() i32 {
2 return 1234;
3}
test/cases/ir_block_deps.zig+3-1
...@@ -11,7 +11,9 @@ fn foo(id: u64) !i32 {...@@ -11,7 +11,9 @@ fn foo(id: u64) !i32 {
11 };11 };
12}12}
1313
14fn getErrInt() error!i32 { return 0; }14fn getErrInt() error!i32 {
15 return 0;
16}
1517
16test "ir block deps" {18test "ir block deps" {
17 assert((foo(1) catch unreachable) == 0);19 assert((foo(1) catch unreachable) == 0);
test/cases/math.zig+40-52
...@@ -28,25 +28,12 @@ fn testDivision() void {...@@ -28,25 +28,12 @@ fn testDivision() void {
28 assert(divTrunc(f32, -5.0, 3.0) == -1.0);28 assert(divTrunc(f32, -5.0, 3.0) == -1.0);
2929
30 comptime {30 comptime {
31 assert(31 assert(1194735857077236777412821811143690633098347576 % 508740759824825164163191790951174292733114988 == 177254337427586449086438229241342047632117600);
32 1194735857077236777412821811143690633098347576 %32 assert(@rem(-1194735857077236777412821811143690633098347576, 508740759824825164163191790951174292733114988) == -177254337427586449086438229241342047632117600);
33 508740759824825164163191790951174292733114988 ==33 assert(1194735857077236777412821811143690633098347576 / 508740759824825164163191790951174292733114988 == 2);
34 177254337427586449086438229241342047632117600);34 assert(@divTrunc(-1194735857077236777412821811143690633098347576, 508740759824825164163191790951174292733114988) == -2);
35 assert(@rem(-1194735857077236777412821811143690633098347576,35 assert(@divTrunc(1194735857077236777412821811143690633098347576, -508740759824825164163191790951174292733114988) == -2);
36 508740759824825164163191790951174292733114988) ==36 assert(@divTrunc(-1194735857077236777412821811143690633098347576, -508740759824825164163191790951174292733114988) == 2);
37 -177254337427586449086438229241342047632117600);
38 assert(1194735857077236777412821811143690633098347576 /
39 508740759824825164163191790951174292733114988 ==
40 2);
41 assert(@divTrunc(-1194735857077236777412821811143690633098347576,
42 508740759824825164163191790951174292733114988) ==
43 -2);
44 assert(@divTrunc(1194735857077236777412821811143690633098347576,
45 -508740759824825164163191790951174292733114988) ==
46 -2);
47 assert(@divTrunc(-1194735857077236777412821811143690633098347576,
48 -508740759824825164163191790951174292733114988) ==
49 2);
50 assert(4126227191251978491697987544882340798050766755606969681711 % 10 == 1);37 assert(4126227191251978491697987544882340798050766755606969681711 % 10 == 1);
51 }38 }
52}39}
...@@ -114,18 +101,28 @@ fn ctz(x: var) usize {...@@ -114,18 +101,28 @@ fn ctz(x: var) usize {
114101
115test "assignment operators" {102test "assignment operators" {
116 var i: u32 = 0;103 var i: u32 = 0;
117 i += 5; assert(i == 5);104 i += 5;
118 i -= 2; assert(i == 3);105 assert(i == 5);
119 i *= 20; assert(i == 60);106 i -= 2;
120 i /= 3; assert(i == 20);107 assert(i == 3);
121 i %= 11; assert(i == 9);108 i *= 20;
122 i <<= 1; assert(i == 18);109 assert(i == 60);
123 i >>= 2; assert(i == 4);110 i /= 3;
111 assert(i == 20);
112 i %= 11;
113 assert(i == 9);
114 i <<= 1;
115 assert(i == 18);
116 i >>= 2;
117 assert(i == 4);
124 i = 6;118 i = 6;
125 i &= 5; assert(i == 4);119 i &= 5;
126 i ^= 6; assert(i == 2);120 assert(i == 4);
121 i ^= 6;
122 assert(i == 2);
127 i = 6;123 i = 6;
128 i |= 3; assert(i == 7);124 i |= 3;
125 assert(i == 7);
129}126}
130127
131test "three expr in a row" {128test "three expr in a row" {
...@@ -138,7 +135,7 @@ fn testThreeExprInARow(f: bool, t: bool) void {...@@ -138,7 +135,7 @@ fn testThreeExprInARow(f: bool, t: bool) void {
138 assertFalse(1 | 2 | 4 != 7);135 assertFalse(1 | 2 | 4 != 7);
139 assertFalse(3 ^ 6 ^ 8 != 13);136 assertFalse(3 ^ 6 ^ 8 != 13);
140 assertFalse(7 & 14 & 28 != 4);137 assertFalse(7 & 14 & 28 != 4);
141 assertFalse(9 << 1 << 2 != 9 << 3);138 assertFalse(9 << 1 << 2 != 9 << 3);
142 assertFalse(90 >> 1 >> 2 != 90 >> 3);139 assertFalse(90 >> 1 >> 2 != 90 >> 3);
143 assertFalse(100 - 1 + 1000 != 1099);140 assertFalse(100 - 1 + 1000 != 1099);
144 assertFalse(5 * 4 / 2 % 3 != 1);141 assertFalse(5 * 4 / 2 % 3 != 1);
...@@ -150,7 +147,6 @@ fn assertFalse(b: bool) void {...@@ -150,7 +147,6 @@ fn assertFalse(b: bool) void {
150 assert(!b);147 assert(!b);
151}148}
152149
153
154test "const number literal" {150test "const number literal" {
155 const one = 1;151 const one = 1;
156 const eleven = ten + one;152 const eleven = ten + one;
...@@ -159,8 +155,6 @@ test "const number literal" {...@@ -159,8 +155,6 @@ test "const number literal" {
159}155}
160const ten = 10;156const ten = 10;
161157
162
163
164test "unsigned wrapping" {158test "unsigned wrapping" {
165 testUnsignedWrappingEval(@maxValue(u32));159 testUnsignedWrappingEval(@maxValue(u32));
166 comptime testUnsignedWrappingEval(@maxValue(u32));160 comptime testUnsignedWrappingEval(@maxValue(u32));
...@@ -214,8 +208,12 @@ const DivResult = struct {...@@ -214,8 +208,12 @@ const DivResult = struct {
214};208};
215209
216test "binary not" {210test "binary not" {
217 assert(comptime x: {break :x ~u16(0b1010101010101010) == 0b0101010101010101;});211 assert(comptime x: {
218 assert(comptime x: {break :x ~u64(2147483647) == 18446744071562067968;});212 break :x ~u16(0b1010101010101010) == 0b0101010101010101;
213 });
214 assert(comptime x: {
215 break :x ~u64(2147483647) == 18446744071562067968;
216 });
219 testBinaryNot(0b1010101010101010);217 testBinaryNot(0b1010101010101010);
220}218}
221219
...@@ -319,27 +317,15 @@ fn testShrExact(x: u8) void {...@@ -319,27 +317,15 @@ fn testShrExact(x: u8) void {
319317
320test "big number addition" {318test "big number addition" {
321 comptime {319 comptime {
322 assert(320 assert(35361831660712422535336160538497375248 + 101752735581729509668353361206450473702 == 137114567242441932203689521744947848950);
323 35361831660712422535336160538497375248 +321 assert(594491908217841670578297176641415611445982232488944558774612 + 390603545391089362063884922208143568023166603618446395589768 == 985095453608931032642182098849559179469148836107390954364380);
324 101752735581729509668353361206450473702 ==
325 137114567242441932203689521744947848950);
326 assert(
327 594491908217841670578297176641415611445982232488944558774612 +
328 390603545391089362063884922208143568023166603618446395589768 ==
329 985095453608931032642182098849559179469148836107390954364380);
330 }322 }
331}323}
332324
333test "big number multiplication" {325test "big number multiplication" {
334 comptime {326 comptime {
335 assert(327 assert(45960427431263824329884196484953148229 * 128339149605334697009938835852565949723 == 5898522172026096622534201617172456926982464453350084962781392314016180490567);
336 45960427431263824329884196484953148229 *328 assert(594491908217841670578297176641415611445982232488944558774612 * 390603545391089362063884922208143568023166603618446395589768 == 232210647056203049913662402532976186578842425262306016094292237500303028346593132411865381225871291702600263463125370016);
337 128339149605334697009938835852565949723 ==
338 5898522172026096622534201617172456926982464453350084962781392314016180490567);
339 assert(
340 594491908217841670578297176641415611445982232488944558774612 *
341 390603545391089362063884922208143568023166603618446395589768 ==
342 232210647056203049913662402532976186578842425262306016094292237500303028346593132411865381225871291702600263463125370016);
343 }329 }
344}330}
345331
...@@ -380,7 +366,9 @@ test "f128" {...@@ -380,7 +366,9 @@ test "f128" {
380 comptime test_f128();366 comptime test_f128();
381}367}
382368
383fn make_f128(x: f128) f128 { return x; }369fn make_f128(x: f128) f128 {
370 return x;
371}
384372
385fn test_f128() void {373fn test_f128() void {
386 assert(@sizeOf(f128) == 16);374 assert(@sizeOf(f128) == 16);
test/cases/misc.zig+138-87
...@@ -4,6 +4,7 @@ const cstr = @import("std").cstr;...@@ -4,6 +4,7 @@ const cstr = @import("std").cstr;
4const builtin = @import("builtin");4const builtin = @import("builtin");
55
6// normal comment6// normal comment
7
7/// this is a documentation comment8/// this is a documentation comment
8/// doc comment line 29/// doc comment line 2
9fn emptyFunctionWithComments() void {}10fn emptyFunctionWithComments() void {}
...@@ -16,8 +17,7 @@ comptime {...@@ -16,8 +17,7 @@ comptime {
16 @export("disabledExternFn", disabledExternFn, builtin.GlobalLinkage.Internal);17 @export("disabledExternFn", disabledExternFn, builtin.GlobalLinkage.Internal);
17}18}
1819
19extern fn disabledExternFn() void {20extern fn disabledExternFn() void {}
20}
2121
22test "call disabled extern fn" {22test "call disabled extern fn" {
23 disabledExternFn();23 disabledExternFn();
...@@ -110,17 +110,29 @@ fn testShortCircuit(f: bool, t: bool) void {...@@ -110,17 +110,29 @@ fn testShortCircuit(f: bool, t: bool) void {
110 var hit_3 = f;110 var hit_3 = f;
111 var hit_4 = f;111 var hit_4 = f;
112112
113 if (t or x: {assert(f); break :x f;}) {113 if (t or x: {
114 assert(f);
115 break :x f;
116 }) {
114 hit_1 = t;117 hit_1 = t;
115 }118 }
116 if (f or x: { hit_2 = t; break :x f; }) {119 if (f or x: {
120 hit_2 = t;
121 break :x f;
122 }) {
117 assert(f);123 assert(f);
118 }124 }
119125
120 if (t and x: { hit_3 = t; break :x f; }) {126 if (t and x: {
127 hit_3 = t;
128 break :x f;
129 }) {
121 assert(f);130 assert(f);
122 }131 }
123 if (f and x: {assert(f); break :x f;}) {132 if (f and x: {
133 assert(f);
134 break :x f;
135 }) {
124 assert(f);136 assert(f);
125 } else {137 } else {
126 hit_4 = t;138 hit_4 = t;
...@@ -146,8 +158,8 @@ test "return string from function" {...@@ -146,8 +158,8 @@ test "return string from function" {
146 assert(mem.eql(u8, first4KeysOfHomeRow(), "aoeu"));158 assert(mem.eql(u8, first4KeysOfHomeRow(), "aoeu"));
147}159}
148160
149const g1 : i32 = 1233 + 1;161const g1: i32 = 1233 + 1;
150var g2 : i32 = 0;162var g2: i32 = 0;
151163
152test "global variables" {164test "global variables" {
153 assert(g2 == 0);165 assert(g2 == 0);
...@@ -155,10 +167,9 @@ test "global variables" {...@@ -155,10 +167,9 @@ test "global variables" {
155 assert(g2 == 1234);167 assert(g2 == 1234);
156}168}
157169
158
159test "memcpy and memset intrinsics" {170test "memcpy and memset intrinsics" {
160 var foo : [20]u8 = undefined;171 var foo: [20]u8 = undefined;
161 var bar : [20]u8 = undefined;172 var bar: [20]u8 = undefined;
162173
163 @memset(&foo[0], 'A', foo.len);174 @memset(&foo[0], 'A', foo.len);
164 @memcpy(&bar[0], &foo[0], bar.len);175 @memcpy(&bar[0], &foo[0], bar.len);
...@@ -167,12 +178,14 @@ test "memcpy and memset intrinsics" {...@@ -167,12 +178,14 @@ test "memcpy and memset intrinsics" {
167}178}
168179
169test "builtin static eval" {180test "builtin static eval" {
170 const x : i32 = comptime x: {break :x 1 + 2 + 3;};181 const x: i32 = comptime x: {
182 break :x 1 + 2 + 3;
183 };
171 assert(x == comptime 6);184 assert(x == comptime 6);
172}185}
173186
174test "slicing" {187test "slicing" {
175 var array : [20]i32 = undefined;188 var array: [20]i32 = undefined;
176189
177 array[5] = 1234;190 array[5] = 1234;
178191
...@@ -187,15 +200,15 @@ test "slicing" {...@@ -187,15 +200,15 @@ test "slicing" {
187 if (slice_rest.len != 10) unreachable;200 if (slice_rest.len != 10) unreachable;
188}201}
189202
190
191test "constant equal function pointers" {203test "constant equal function pointers" {
192 const alias = emptyFn;204 const alias = emptyFn;
193 assert(comptime x: {break :x emptyFn == alias;});205 assert(comptime x: {
206 break :x emptyFn == alias;
207 });
194}208}
195209
196fn emptyFn() void {}210fn emptyFn() void {}
197211
198
199test "hex escape" {212test "hex escape" {
200 assert(mem.eql(u8, "\x68\x65\x6c\x6c\x6f", "hello"));213 assert(mem.eql(u8, "\x68\x65\x6c\x6c\x6f", "hello"));
201}214}
...@@ -219,7 +232,7 @@ test "string escapes" {...@@ -219,7 +232,7 @@ test "string escapes" {
219}232}
220233
221test "multiline string" {234test "multiline string" {
222 const s1 =235 const s1 =
223 \\one236 \\one
224 \\two)237 \\two)
225 \\three238 \\three
...@@ -229,7 +242,7 @@ test "multiline string" {...@@ -229,7 +242,7 @@ test "multiline string" {
229}242}
230243
231test "multiline C string" {244test "multiline C string" {
232 const s1 =245 const s1 =
233 c\\one246 c\\one
234 c\\two)247 c\\two)
235 c\\three248 c\\three
...@@ -238,18 +251,16 @@ test "multiline C string" {...@@ -238,18 +251,16 @@ test "multiline C string" {
238 assert(cstr.cmp(s1, s2) == 0);251 assert(cstr.cmp(s1, s2) == 0);
239}252}
240253
241
242test "type equality" {254test "type equality" {
243 assert(&const u8 != &u8);255 assert(&const u8 != &u8);
244}256}
245257
246
247const global_a: i32 = 1234;258const global_a: i32 = 1234;
248const global_b: &const i32 = &global_a;259const global_b: &const i32 = &global_a;
249const global_c: &const f32 = @ptrCast(&const f32, global_b);260const global_c: &const f32 = @ptrCast(&const f32, global_b);
250test "compile time global reinterpret" {261test "compile time global reinterpret" {
251 const d = @ptrCast(&const i32, global_c);262 const d = @ptrCast(&const i32, global_c);
252 assert(*d == 1234);263 assert(d.* == 1234);
253}264}
254265
255test "explicit cast maybe pointers" {266test "explicit cast maybe pointers" {
...@@ -261,12 +272,11 @@ test "generic malloc free" {...@@ -261,12 +272,11 @@ test "generic malloc free" {
261 const a = memAlloc(u8, 10) catch unreachable;272 const a = memAlloc(u8, 10) catch unreachable;
262 memFree(u8, a);273 memFree(u8, a);
263}274}
264var some_mem : [100]u8 = undefined;275var some_mem: [100]u8 = undefined;
265fn memAlloc(comptime T: type, n: usize) error![]T {276fn memAlloc(comptime T: type, n: usize) error![]T {
266 return @ptrCast(&T, &some_mem[0])[0..n];277 return @ptrCast(&T, &some_mem[0])[0..n];
267}278}
268fn memFree(comptime T: type, memory: []T) void { }279fn memFree(comptime T: type, memory: []T) void {}
269
270280
271test "cast undefined" {281test "cast undefined" {
272 const array: [100]u8 = undefined;282 const array: [100]u8 = undefined;
...@@ -275,32 +285,35 @@ test "cast undefined" {...@@ -275,32 +285,35 @@ test "cast undefined" {
275}285}
276fn testCastUndefined(x: []const u8) void {}286fn testCastUndefined(x: []const u8) void {}
277287
278
279test "cast small unsigned to larger signed" {288test "cast small unsigned to larger signed" {
280 assert(castSmallUnsignedToLargerSigned1(200) == i16(200));289 assert(castSmallUnsignedToLargerSigned1(200) == i16(200));
281 assert(castSmallUnsignedToLargerSigned2(9999) == i64(9999));290 assert(castSmallUnsignedToLargerSigned2(9999) == i64(9999));
282}291}
283fn castSmallUnsignedToLargerSigned1(x: u8) i16 { return x; }292fn castSmallUnsignedToLargerSigned1(x: u8) i16 {
284fn castSmallUnsignedToLargerSigned2(x: u16) i64 { return x; }293 return x;
285294}
295fn castSmallUnsignedToLargerSigned2(x: u16) i64 {
296 return x;
297}
286298
287test "implicit cast after unreachable" {299test "implicit cast after unreachable" {
288 assert(outer() == 1234);300 assert(outer() == 1234);
289}301}
290fn inner() i32 { return 1234; }302fn inner() i32 {
303 return 1234;
304}
291fn outer() i64 {305fn outer() i64 {
292 return inner();306 return inner();
293}307}
294308
295
296test "pointer dereferencing" {309test "pointer dereferencing" {
297 var x = i32(3);310 var x = i32(3);
298 const y = &x;311 const y = &x;
299312
300 *y += 1;313 y.* += 1;
301314
302 assert(x == 4);315 assert(x == 4);
303 assert(*y == 4);316 assert(y.* == 4);
304}317}
305318
306test "call result of if else expression" {319test "call result of if else expression" {
...@@ -310,9 +323,12 @@ test "call result of if else expression" {...@@ -310,9 +323,12 @@ test "call result of if else expression" {
310fn f2(x: bool) []const u8 {323fn f2(x: bool) []const u8 {
311 return (if (x) fA else fB)();324 return (if (x) fA else fB)();
312}325}
313fn fA() []const u8 { return "a"; }326fn fA() []const u8 {
314fn fB() []const u8 { return "b"; }327 return "a";
315328}
329fn fB() []const u8 {
330 return "b";
331}
316332
317test "const expression eval handling of variables" {333test "const expression eval handling of variables" {
318 var x = true;334 var x = true;
...@@ -321,8 +337,6 @@ test "const expression eval handling of variables" {...@@ -321,8 +337,6 @@ test "const expression eval handling of variables" {
321 }337 }
322}338}
323339
324
325
326test "constant enum initialization with differing sizes" {340test "constant enum initialization with differing sizes" {
327 test3_1(test3_foo);341 test3_1(test3_foo);
328 test3_2(test3_bar);342 test3_2(test3_bar);
...@@ -336,10 +350,17 @@ const Test3Point = struct {...@@ -336,10 +350,17 @@ const Test3Point = struct {
336 x: i32,350 x: i32,
337 y: i32,351 y: i32,
338};352};
339const test3_foo = Test3Foo { .Three = Test3Point {.x = 3, .y = 4}};353const test3_foo = Test3Foo {
340const test3_bar = Test3Foo { .Two = 13};354 .Three = Test3Point {
355 .x = 3,
356 .y = 4,
357 },
358};
359const test3_bar = Test3Foo {
360 .Two = 13,
361};
341fn test3_1(f: &const Test3Foo) void {362fn test3_1(f: &const Test3Foo) void {
342 switch (*f) {363 switch (f.*) {
343 Test3Foo.Three => |pt| {364 Test3Foo.Three => |pt| {
344 assert(pt.x == 3);365 assert(pt.x == 3);
345 assert(pt.y == 4);366 assert(pt.y == 4);
...@@ -348,7 +369,7 @@ fn test3_1(f: &const Test3Foo) void {...@@ -348,7 +369,7 @@ fn test3_1(f: &const Test3Foo) void {
348 }369 }
349}370}
350fn test3_2(f: &const Test3Foo) void {371fn test3_2(f: &const Test3Foo) void {
351 switch (*f) {372 switch (f.*) {
352 Test3Foo.Two => |x| {373 Test3Foo.Two => |x| {
353 assert(x == 13);374 assert(x == 13);
354 },375 },
...@@ -356,23 +377,19 @@ fn test3_2(f: &const Test3Foo) void {...@@ -356,23 +377,19 @@ fn test3_2(f: &const Test3Foo) void {
356 }377 }
357}378}
358379
359
360test "character literals" {380test "character literals" {
361 assert('\'' == single_quote);381 assert('\'' == single_quote);
362}382}
363const single_quote = '\'';383const single_quote = '\'';
364384
365
366
367test "take address of parameter" {385test "take address of parameter" {
368 testTakeAddressOfParameter(12.34);386 testTakeAddressOfParameter(12.34);
369}387}
370fn testTakeAddressOfParameter(f: f32) void {388fn testTakeAddressOfParameter(f: f32) void {
371 const f_ptr = &f;389 const f_ptr = &f;
372 assert(*f_ptr == 12.34);390 assert(f_ptr.* == 12.34);
373}391}
374392
375
376test "pointer comparison" {393test "pointer comparison" {
377 const a = ([]const u8)("a");394 const a = ([]const u8)("a");
378 const b = &a;395 const b = &a;
...@@ -382,23 +399,30 @@ fn ptrEql(a: &const []const u8, b: &const []const u8) bool {...@@ -382,23 +399,30 @@ fn ptrEql(a: &const []const u8, b: &const []const u8) bool {
382 return a == b;399 return a == b;
383}400}
384401
385
386test "C string concatenation" {402test "C string concatenation" {
387 const a = c"OK" ++ c" IT " ++ c"WORKED";403 const a = c"OK" ++ c" IT " ++ c"WORKED";
388 const b = c"OK IT WORKED";404 const b = c"OK IT WORKED";
389405
390 const len = cstr.len(b);406 const len = cstr.len(b);
391 const len_with_null = len + 1;407 const len_with_null = len + 1;
392 {var i: u32 = 0; while (i < len_with_null) : (i += 1) {408 {
393 assert(a[i] == b[i]);409 var i: u32 = 0;
394 }}410 while (i < len_with_null) : (i += 1) {
411 assert(a[i] == b[i]);
412 }
413 }
395 assert(a[len] == 0);414 assert(a[len] == 0);
396 assert(b[len] == 0);415 assert(b[len] == 0);
397}416}
398417
399test "cast slice to u8 slice" {418test "cast slice to u8 slice" {
400 assert(@sizeOf(i32) == 4);419 assert(@sizeOf(i32) == 4);
401 var big_thing_array = []i32{1, 2, 3, 4};420 var big_thing_array = []i32 {
421 1,
422 2,
423 3,
424 4,
425 };
402 const big_thing_slice: []i32 = big_thing_array[0..];426 const big_thing_slice: []i32 = big_thing_array[0..];
403 const bytes = ([]u8)(big_thing_slice);427 const bytes = ([]u8)(big_thing_slice);
404 assert(bytes.len == 4 * 4);428 assert(bytes.len == 4 * 4);
...@@ -421,25 +445,22 @@ test "pointer to void return type" {...@@ -421,25 +445,22 @@ test "pointer to void return type" {
421}445}
422fn testPointerToVoidReturnType() error!void {446fn testPointerToVoidReturnType() error!void {
423 const a = testPointerToVoidReturnType2();447 const a = testPointerToVoidReturnType2();
424 return *a;448 return a.*;
425}449}
426const test_pointer_to_void_return_type_x = void{};450const test_pointer_to_void_return_type_x = void{};
427fn testPointerToVoidReturnType2() &const void {451fn testPointerToVoidReturnType2() &const void {
428 return &test_pointer_to_void_return_type_x;452 return &test_pointer_to_void_return_type_x;
429}453}
430454
431
432test "non const ptr to aliased type" {455test "non const ptr to aliased type" {
433 const int = i32;456 const int = i32;
434 assert(?&int == ?&i32);457 assert(?&int == ?&i32);
435}458}
436459
437
438
439test "array 2D const double ptr" {460test "array 2D const double ptr" {
440 const rect_2d_vertexes = [][1]f32 {461 const rect_2d_vertexes = [][1]f32 {
441 []f32{1.0},462 []f32 {1.0},
442 []f32{2.0},463 []f32 {2.0},
443 };464 };
444 testArray2DConstDoublePtr(&rect_2d_vertexes[0][0]);465 testArray2DConstDoublePtr(&rect_2d_vertexes[0][0]);
445}466}
...@@ -450,10 +471,21 @@ fn testArray2DConstDoublePtr(ptr: &const f32) void {...@@ -450,10 +471,21 @@ fn testArray2DConstDoublePtr(ptr: &const f32) void {
450}471}
451472
452const Tid = builtin.TypeId;473const Tid = builtin.TypeId;
453const AStruct = struct { x: i32, };474const AStruct = struct {
454const AnEnum = enum { One, Two, };475 x: i32,
455const AUnionEnum = union(enum) { One: i32, Two: void, };476};
456const AUnion = union { One: void, Two: void };477const AnEnum = enum {
478 One,
479 Two,
480};
481const AUnionEnum = union(enum) {
482 One: i32,
483 Two: void,
484};
485const AUnion = union {
486 One: void,
487 Two: void,
488};
457489
458test "@typeId" {490test "@typeId" {
459 comptime {491 comptime {
...@@ -481,9 +513,11 @@ test "@typeId" {...@@ -481,9 +513,11 @@ test "@typeId" {
481 assert(@typeId(@typeOf(AUnionEnum.One)) == Tid.Enum);513 assert(@typeId(@typeOf(AUnionEnum.One)) == Tid.Enum);
482 assert(@typeId(AUnionEnum) == Tid.Union);514 assert(@typeId(AUnionEnum) == Tid.Union);
483 assert(@typeId(AUnion) == Tid.Union);515 assert(@typeId(AUnion) == Tid.Union);
484 assert(@typeId(fn()void) == Tid.Fn);516 assert(@typeId(fn() void) == Tid.Fn);
485 assert(@typeId(@typeOf(builtin)) == Tid.Namespace);517 assert(@typeId(@typeOf(builtin)) == Tid.Namespace);
486 assert(@typeId(@typeOf(x: {break :x this;})) == Tid.Block);518 assert(@typeId(@typeOf(x: {
519 break :x this;
520 })) == Tid.Block);
487 // TODO bound fn521 // TODO bound fn
488 // TODO arg tuple522 // TODO arg tuple
489 // TODO opaque523 // TODO opaque
...@@ -499,8 +533,7 @@ test "@canImplicitCast" {...@@ -499,8 +533,7 @@ test "@canImplicitCast" {
499}533}
500534
501test "@typeName" {535test "@typeName" {
502 const Struct = struct {536 const Struct = struct {};
503 };
504 const Union = union {537 const Union = union {
505 unused: u8,538 unused: u8,
506 };539 };
...@@ -525,14 +558,19 @@ fn TypeFromFn(comptime T: type) type {...@@ -525,14 +558,19 @@ fn TypeFromFn(comptime T: type) type {
525test "volatile load and store" {558test "volatile load and store" {
526 var number: i32 = 1234;559 var number: i32 = 1234;
527 const ptr = (&volatile i32)(&number);560 const ptr = (&volatile i32)(&number);
528 *ptr += 1;561 ptr.* += 1;
529 assert(*ptr == 1235);562 assert(ptr.* == 1235);
530}563}
531564
532test "slice string literal has type []const u8" {565test "slice string literal has type []const u8" {
533 comptime {566 comptime {
534 assert(@typeOf("aoeu"[0..]) == []const u8);567 assert(@typeOf("aoeu"[0..]) == []const u8);
535 const array = []i32{1, 2, 3, 4};568 const array = []i32 {
569 1,
570 2,
571 3,
572 4,
573 };
536 assert(@typeOf(array[0..]) == []const i32);574 assert(@typeOf(array[0..]) == []const i32);
537 }575 }
538}576}
...@@ -544,12 +582,15 @@ const GDTEntry = struct {...@@ -544,12 +582,15 @@ const GDTEntry = struct {
544 field: i32,582 field: i32,
545};583};
546var gdt = []GDTEntry {584var gdt = []GDTEntry {
547 GDTEntry {.field = 1},585 GDTEntry {
548 GDTEntry {.field = 2},586 .field = 1,
587 },
588 GDTEntry {
589 .field = 2,
590 },
549};591};
550var global_ptr = &gdt[0];592var global_ptr = &gdt[0];
551593
552
553// can't really run this test but we can make sure it has no compile error594// can't really run this test but we can make sure it has no compile error
554// and generates code595// and generates code
555const vram = @intToPtr(&volatile u8, 0x20000000)[0..0x8000];596const vram = @intToPtr(&volatile u8, 0x20000000)[0..0x8000];
...@@ -584,7 +625,7 @@ test "comptime if inside runtime while which unconditionally breaks" {...@@ -584,7 +625,7 @@ test "comptime if inside runtime while which unconditionally breaks" {
584}625}
585fn testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(cond: bool) void {626fn testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(cond: bool) void {
586 while (cond) {627 while (cond) {
587 if (false) { }628 if (false) {}
588 break;629 break;
589 }630 }
590}631}
...@@ -607,7 +648,9 @@ fn testStructInFn() void {...@@ -607,7 +648,9 @@ fn testStructInFn() void {
607 kind: BlockKind,648 kind: BlockKind,
608 };649 };
609650
610 var block = Block { .kind = 1234 };651 var block = Block {
652 .kind = 1234,
653 };
611654
612 block.kind += 1;655 block.kind += 1;
613656
...@@ -617,7 +660,9 @@ fn testStructInFn() void {...@@ -617,7 +660,9 @@ fn testStructInFn() void {
617fn fnThatClosesOverLocalConst() type {660fn fnThatClosesOverLocalConst() type {
618 const c = 1;661 const c = 1;
619 return struct {662 return struct {
620 fn g() i32 { return c; }663 fn g() i32 {
664 return c;
665 }
621 };666 };
622}667}
623668
...@@ -635,22 +680,29 @@ fn thisIsAColdFn() void {...@@ -635,22 +680,29 @@ fn thisIsAColdFn() void {
635 @setCold(true);680 @setCold(true);
636}681}
637682
638683const PackedStruct = packed struct {
639const PackedStruct = packed struct { a: u8, b: u8, };684 a: u8,
640const PackedUnion = packed union { a: u8, b: u32, };685 b: u8,
641const PackedEnum = packed enum { A, B, };686};
687const PackedUnion = packed union {
688 a: u8,
689 b: u32,
690};
691const PackedEnum = packed enum {
692 A,
693 B,
694};
642695
643test "packed struct, enum, union parameters in extern function" {696test "packed struct, enum, union parameters in extern function" {
644 testPackedStuff(697 testPackedStuff(PackedStruct {
645 PackedStruct{.a = 1, .b = 2},698 .a = 1,
646 PackedUnion{.a = 1},699 .b = 2,
647 PackedEnum.A,700 }, PackedUnion {
648 );701 .a = 1,
649}702 }, PackedEnum.A);
650
651export fn testPackedStuff(a: &const PackedStruct, b: &const PackedUnion, c: PackedEnum) void {
652}703}
653704
705export fn testPackedStuff(a: &const PackedStruct, b: &const PackedUnion, c: PackedEnum) void {}
654706
655test "slicing zero length array" {707test "slicing zero length array" {
656 const s1 = ""[0..];708 const s1 = ""[0..];
...@@ -661,7 +713,6 @@ test "slicing zero length array" {...@@ -661,7 +713,6 @@ test "slicing zero length array" {
661 assert(mem.eql(u32, s2, []u32{}));713 assert(mem.eql(u32, s2, []u32{}));
662}714}
663715
664
665const addr1 = @ptrCast(&const u8, emptyFn);716const addr1 = @ptrCast(&const u8, emptyFn);
666test "comptime cast fn to ptr" {717test "comptime cast fn to ptr" {
667 const addr2 = @ptrCast(&const u8, emptyFn);718 const addr2 = @ptrCast(&const u8, emptyFn);
test/cases/namespace_depends_on_compile_var/index.zig+1-1
...@@ -8,7 +8,7 @@ test "namespace depends on compile var" {...@@ -8,7 +8,7 @@ test "namespace depends on compile var" {
8 assert(!some_namespace.a_bool);8 assert(!some_namespace.a_bool);
9 }9 }
10}10}
11const some_namespace = switch(builtin.os) {11const some_namespace = switch (builtin.os) {
12 builtin.Os.linux => @import("a.zig"),12 builtin.Os.linux => @import("a.zig"),
13 else => @import("b.zig"),13 else => @import("b.zig"),
14};14};
test/cases/null.zig+12-15
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const assert = @import("std").debug.assert;1const assert = @import("std").debug.assert;
22
3test "nullable type" {3test "nullable type" {
4 const x : ?bool = true;4 const x: ?bool = true;
55
6 if (x) |y| {6 if (x) |y| {
7 if (y) {7 if (y) {
...@@ -13,13 +13,13 @@ test "nullable type" {...@@ -13,13 +13,13 @@ test "nullable type" {
13 unreachable;13 unreachable;
14 }14 }
1515
16 const next_x : ?i32 = null;16 const next_x: ?i32 = null;
1717
18 const z = next_x ?? 1234;18 const z = next_x ?? 1234;
1919
20 assert(z == 1234);20 assert(z == 1234);
2121
22 const final_x : ?i32 = 13;22 const final_x: ?i32 = 13;
2323
24 const num = final_x ?? unreachable;24 const num = final_x ?? unreachable;
2525
...@@ -30,19 +30,17 @@ test "test maybe object and get a pointer to the inner value" {...@@ -30,19 +30,17 @@ test "test maybe object and get a pointer to the inner value" {
30 var maybe_bool: ?bool = true;30 var maybe_bool: ?bool = true;
3131
32 if (maybe_bool) |*b| {32 if (maybe_bool) |*b| {
33 *b = false;33 b.* = false;
34 }34 }
3535
36 assert(??maybe_bool == false);36 assert(??maybe_bool == false);
37}37}
3838
39
40test "rhs maybe unwrap return" {39test "rhs maybe unwrap return" {
41 const x: ?bool = true;40 const x: ?bool = true;
42 const y = x ?? return;41 const y = x ?? return;
43}42}
4443
45
46test "maybe return" {44test "maybe return" {
47 maybeReturnImpl();45 maybeReturnImpl();
48 comptime maybeReturnImpl();46 comptime maybeReturnImpl();
...@@ -50,8 +48,7 @@ test "maybe return" {...@@ -50,8 +48,7 @@ test "maybe return" {
5048
51fn maybeReturnImpl() void {49fn maybeReturnImpl() void {
52 assert(??foo(1235));50 assert(??foo(1235));
53 if (foo(null) != null)51 if (foo(null) != null) unreachable;
54 unreachable;
55 assert(!??foo(1234));52 assert(!??foo(1234));
56}53}
5754
...@@ -60,12 +57,16 @@ fn foo(x: ?i32) ?bool {...@@ -60,12 +57,16 @@ fn foo(x: ?i32) ?bool {
60 return value > 1234;57 return value > 1234;
61}58}
6259
63
64test "if var maybe pointer" {60test "if var maybe pointer" {
65 assert(shouldBeAPlus1(Particle {.a = 14, .b = 1, .c = 1, .d = 1}) == 15);61 assert(shouldBeAPlus1(Particle {
62 .a = 14,
63 .b = 1,
64 .c = 1,
65 .d = 1,
66 }) == 15);
66}67}
67fn shouldBeAPlus1(p: &const Particle) u64 {68fn shouldBeAPlus1(p: &const Particle) u64 {
68 var maybe_particle: ?Particle = *p;69 var maybe_particle: ?Particle = p.*;
69 if (maybe_particle) |*particle| {70 if (maybe_particle) |*particle| {
70 particle.a += 1;71 particle.a += 1;
71 }72 }
...@@ -81,7 +82,6 @@ const Particle = struct {...@@ -81,7 +82,6 @@ const Particle = struct {
81 d: u64,82 d: u64,
82};83};
8384
84
85test "null literal outside function" {85test "null literal outside function" {
86 const is_null = here_is_a_null_literal.context == null;86 const is_null = here_is_a_null_literal.context == null;
87 assert(is_null);87 assert(is_null);
...@@ -96,7 +96,6 @@ const here_is_a_null_literal = SillyStruct {...@@ -96,7 +96,6 @@ const here_is_a_null_literal = SillyStruct {
96 .context = null,96 .context = null,
97};97};
9898
99
100test "test null runtime" {99test "test null runtime" {
101 testTestNullRuntime(null);100 testTestNullRuntime(null);
102}101}
...@@ -123,8 +122,6 @@ fn bar(x: ?void) ?void {...@@ -123,8 +122,6 @@ fn bar(x: ?void) ?void {
123 }122 }
124}123}
125124
126
127
128const StructWithNullable = struct {125const StructWithNullable = struct {
129 field: ?i32,126 field: ?i32,
130};127};
test/cases/ref_var_in_if_after_if_2nd_switch_prong.zig+1-1
...@@ -23,7 +23,7 @@ fn foo(c: bool, k: Num, c2: bool, b: []const u8) void {...@@ -23,7 +23,7 @@ fn foo(c: bool, k: Num, c2: bool, b: []const u8) void {
23 if (c) {23 if (c) {
24 const output_path = b;24 const output_path = b;
2525
26 if (c2) { }26 if (c2) {}
2727
28 a(output_path);28 a(output_path);
29 }29 }
test/cases/reflection.zig+3-2
...@@ -23,7 +23,9 @@ test "reflection: function return type, var args, and param types" {...@@ -23,7 +23,9 @@ test "reflection: function return type, var args, and param types" {
23 }23 }
24}24}
2525
26fn dummy(a: bool, b: i32, c: f32) i32 { return 1234; }26fn dummy(a: bool, b: i32, c: f32) i32 {
27 return 1234;
28}
27fn dummy_varargs(args: ...) void {}29fn dummy_varargs(args: ...) void {}
2830
29test "reflection: struct member types and names" {31test "reflection: struct member types and names" {
...@@ -54,7 +56,6 @@ test "reflection: enum member types and names" {...@@ -54,7 +56,6 @@ test "reflection: enum member types and names" {
54 assert(mem.eql(u8, @memberName(Bar, 2), "Three"));56 assert(mem.eql(u8, @memberName(Bar, 2), "Three"));
55 assert(mem.eql(u8, @memberName(Bar, 3), "Four"));57 assert(mem.eql(u8, @memberName(Bar, 3), "Four"));
56 }58 }
57
58}59}
5960
60test "reflection: @field" {61test "reflection: @field" {
test/cases/slice.zig+6-2
...@@ -18,7 +18,11 @@ test "slice child property" {...@@ -18,7 +18,11 @@ test "slice child property" {
18}18}
1919
20test "runtime safety lets us slice from len..len" {20test "runtime safety lets us slice from len..len" {
21 var an_array = []u8{1, 2, 3};21 var an_array = []u8 {
22 1,
23 2,
24 3,
25 };
22 assert(mem.eql(u8, sliceFromLenToLen(an_array[0..], 3, 3), ""));26 assert(mem.eql(u8, sliceFromLenToLen(an_array[0..], 3, 3), ""));
23}27}
2428
...@@ -27,7 +31,7 @@ fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) []u8 {...@@ -27,7 +31,7 @@ fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) []u8 {
27}31}
2832
29test "implicitly cast array of size 0 to slice" {33test "implicitly cast array of size 0 to slice" {
30 var msg = []u8 {};34 var msg = []u8{};
31 assertLenIsZero(msg);35 assertLenIsZero(msg);
32}36}
3337
test/cases/struct.zig+48-35
...@@ -2,9 +2,11 @@ const assert = @import("std").debug.assert;...@@ -2,9 +2,11 @@ const assert = @import("std").debug.assert;
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4const StructWithNoFields = struct {4const StructWithNoFields = struct {
5 fn add(a: i32, b: i32) i32 { return a + b; }5 fn add(a: i32, b: i32) i32 {
6 return a + b;
7 }
6};8};
7const empty_global_instance = StructWithNoFields {};9const empty_global_instance = StructWithNoFields{};
810
9test "call struct static method" {11test "call struct static method" {
10 const result = StructWithNoFields.add(3, 4);12 const result = StructWithNoFields.add(3, 4);
...@@ -34,12 +36,11 @@ test "void struct fields" {...@@ -34,12 +36,11 @@ test "void struct fields" {
34 assert(@sizeOf(VoidStructFieldsFoo) == 4);36 assert(@sizeOf(VoidStructFieldsFoo) == 4);
35}37}
36const VoidStructFieldsFoo = struct {38const VoidStructFieldsFoo = struct {
37 a : void,39 a: void,
38 b : i32,40 b: i32,
39 c : void,41 c: void,
40};42};
4143
42
43test "structs" {44test "structs" {
44 var foo: StructFoo = undefined;45 var foo: StructFoo = undefined;
45 @memset(@ptrCast(&u8, &foo), 0, @sizeOf(StructFoo));46 @memset(@ptrCast(&u8, &foo), 0, @sizeOf(StructFoo));
...@@ -50,9 +51,9 @@ test "structs" {...@@ -50,9 +51,9 @@ test "structs" {
50 assert(foo.c == 100);51 assert(foo.c == 100);
51}52}
52const StructFoo = struct {53const StructFoo = struct {
53 a : i32,54 a: i32,
54 b : bool,55 b: bool,
55 c : f32,56 c: f32,
56};57};
57fn testFoo(foo: &const StructFoo) void {58fn testFoo(foo: &const StructFoo) void {
58 assert(foo.b);59 assert(foo.b);
...@@ -61,7 +62,6 @@ fn testMutation(foo: &StructFoo) void {...@@ -61,7 +62,6 @@ fn testMutation(foo: &StructFoo) void {
61 foo.c = 100;62 foo.c = 100;
62}63}
6364
64
65const Node = struct {65const Node = struct {
66 val: Val,66 val: Val,
67 next: &Node,67 next: &Node,
...@@ -72,10 +72,10 @@ const Val = struct {...@@ -72,10 +72,10 @@ const Val = struct {
72};72};
7373
74test "struct point to self" {74test "struct point to self" {
75 var root : Node = undefined;75 var root: Node = undefined;
76 root.val.x = 1;76 root.val.x = 1;
7777
78 var node : Node = undefined;78 var node: Node = undefined;
79 node.next = &root;79 node.next = &root;
80 node.val.x = 2;80 node.val.x = 2;
8181
...@@ -85,8 +85,8 @@ test "struct point to self" {...@@ -85,8 +85,8 @@ test "struct point to self" {
85}85}
8686
87test "struct byval assign" {87test "struct byval assign" {
88 var foo1 : StructFoo = undefined;88 var foo1: StructFoo = undefined;
89 var foo2 : StructFoo = undefined;89 var foo2: StructFoo = undefined;
9090
91 foo1.a = 1234;91 foo1.a = 1234;
92 foo2.a = 0;92 foo2.a = 0;
...@@ -96,46 +96,57 @@ test "struct byval assign" {...@@ -96,46 +96,57 @@ test "struct byval assign" {
96}96}
9797
98fn structInitializer() void {98fn structInitializer() void {
99 const val = Val { .x = 42 };99 const val = Val {
100 .x = 42,
101 };
100 assert(val.x == 42);102 assert(val.x == 42);
101}103}
102104
103
104test "fn call of struct field" {105test "fn call of struct field" {
105 assert(callStructField(Foo {.ptr = aFunc,}) == 13);106 assert(callStructField(Foo {
107 .ptr = aFunc,
108 }) == 13);
106}109}
107110
108const Foo = struct {111const Foo = struct {
109 ptr: fn() i32,112 ptr: fn() i32,
110};113};
111114
112fn aFunc() i32 { return 13; }115fn aFunc() i32 {
116 return 13;
117}
113118
114fn callStructField(foo: &const Foo) i32 {119fn callStructField(foo: &const Foo) i32 {
115 return foo.ptr();120 return foo.ptr();
116}121}
117122
118
119test "store member function in variable" {123test "store member function in variable" {
120 const instance = MemberFnTestFoo { .x = 1234, };124 const instance = MemberFnTestFoo {
125 .x = 1234,
126 };
121 const memberFn = MemberFnTestFoo.member;127 const memberFn = MemberFnTestFoo.member;
122 const result = memberFn(instance);128 const result = memberFn(instance);
123 assert(result == 1234);129 assert(result == 1234);
124}130}
125const MemberFnTestFoo = struct {131const MemberFnTestFoo = struct {
126 x: i32,132 x: i32,
127 fn member(foo: &const MemberFnTestFoo) i32 { return foo.x; }133 fn member(foo: &const MemberFnTestFoo) i32 {
134 return foo.x;
135 }
128};136};
129137
130
131test "call member function directly" {138test "call member function directly" {
132 const instance = MemberFnTestFoo { .x = 1234, };139 const instance = MemberFnTestFoo {
140 .x = 1234,
141 };
133 const result = MemberFnTestFoo.member(instance);142 const result = MemberFnTestFoo.member(instance);
134 assert(result == 1234);143 assert(result == 1234);
135}144}
136145
137test "member functions" {146test "member functions" {
138 const r = MemberFnRand {.seed = 1234};147 const r = MemberFnRand {
148 .seed = 1234,
149 };
139 assert(r.getSeed() == 1234);150 assert(r.getSeed() == 1234);
140}151}
141const MemberFnRand = struct {152const MemberFnRand = struct {
...@@ -170,17 +181,16 @@ const EmptyStruct = struct {...@@ -170,17 +181,16 @@ const EmptyStruct = struct {
170 }181 }
171};182};
172183
173
174test "return empty struct from fn" {184test "return empty struct from fn" {
175 _ = testReturnEmptyStructFromFn();185 _ = testReturnEmptyStructFromFn();
176}186}
177const EmptyStruct2 = struct {};187const EmptyStruct2 = struct {};
178fn testReturnEmptyStructFromFn() EmptyStruct2 {188fn testReturnEmptyStructFromFn() EmptyStruct2 {
179 return EmptyStruct2 {};189 return EmptyStruct2{};
180}190}
181191
182test "pass slice of empty struct to fn" {192test "pass slice of empty struct to fn" {
183 assert(testPassSliceOfEmptyStructToFn([]EmptyStruct2{ EmptyStruct2{} }) == 1);193 assert(testPassSliceOfEmptyStructToFn([]EmptyStruct2 {EmptyStruct2{}}) == 1);
184}194}
185fn testPassSliceOfEmptyStructToFn(slice: []const EmptyStruct2) usize {195fn testPassSliceOfEmptyStructToFn(slice: []const EmptyStruct2) usize {
186 return slice.len;196 return slice.len;
...@@ -201,7 +211,6 @@ test "packed struct" {...@@ -201,7 +211,6 @@ test "packed struct" {
201 assert(four == 4);211 assert(four == 4);
202}212}
203213
204
205const BitField1 = packed struct {214const BitField1 = packed struct {
206 a: u3,215 a: u3,
207 b: u3,216 b: u3,
...@@ -301,7 +310,7 @@ test "packed array 24bits" {...@@ -301,7 +310,7 @@ test "packed array 24bits" {
301 assert(@sizeOf(FooArray24Bits) == 2 + 2 * 3 + 2);310 assert(@sizeOf(FooArray24Bits) == 2 + 2 * 3 + 2);
302 }311 }
303312
304 var bytes = []u8{0} ** (@sizeOf(FooArray24Bits) + 1);313 var bytes = []u8 {0} ** (@sizeOf(FooArray24Bits) + 1);
305 bytes[bytes.len - 1] = 0xaa;314 bytes[bytes.len - 1] = 0xaa;
306 const ptr = &([]FooArray24Bits)(bytes[0..bytes.len - 1])[0];315 const ptr = &([]FooArray24Bits)(bytes[0..bytes.len - 1])[0];
307 assert(ptr.a == 0);316 assert(ptr.a == 0);
...@@ -351,7 +360,7 @@ test "aligned array of packed struct" {...@@ -351,7 +360,7 @@ test "aligned array of packed struct" {
351 assert(@sizeOf(FooArrayOfAligned) == 2 * 2);360 assert(@sizeOf(FooArrayOfAligned) == 2 * 2);
352 }361 }
353362
354 var bytes = []u8{0xbb} ** @sizeOf(FooArrayOfAligned);363 var bytes = []u8 {0xbb} ** @sizeOf(FooArrayOfAligned);
355 const ptr = &([]FooArrayOfAligned)(bytes[0..bytes.len])[0];364 const ptr = &([]FooArrayOfAligned)(bytes[0..bytes.len])[0];
356365
357 assert(ptr.a[0].a == 0xbb);366 assert(ptr.a[0].a == 0xbb);
...@@ -360,11 +369,15 @@ test "aligned array of packed struct" {...@@ -360,11 +369,15 @@ test "aligned array of packed struct" {
360 assert(ptr.a[1].b == 0xbb);369 assert(ptr.a[1].b == 0xbb);
361}370}
362371
363
364
365test "runtime struct initialization of bitfield" {372test "runtime struct initialization of bitfield" {
366 const s1 = Nibbles { .x = x1, .y = x1 };373 const s1 = Nibbles {
367 const s2 = Nibbles { .x = u4(x2), .y = u4(x2) };374 .x = x1,
375 .y = x1,
376 };
377 const s2 = Nibbles {
378 .x = u4(x2),
379 .y = u4(x2),
380 };
368381
369 assert(s1.x == x1);382 assert(s1.x == x1);
370 assert(s1.y == x1);383 assert(s1.y == x1);
...@@ -394,7 +407,7 @@ test "native bit field understands endianness" {...@@ -394,7 +407,7 @@ test "native bit field understands endianness" {
394 var all: u64 = 0x7765443322221111;407 var all: u64 = 0x7765443322221111;
395 var bytes: [8]u8 = undefined;408 var bytes: [8]u8 = undefined;
396 @memcpy(&bytes[0], @ptrCast(&u8, &all), 8);409 @memcpy(&bytes[0], @ptrCast(&u8, &all), 8);
397 var bitfields = *@ptrCast(&Bitfields, &bytes[0]);410 var bitfields = @ptrCast(&Bitfields, &bytes[0]).*;
398411
399 assert(bitfields.f1 == 0x1111);412 assert(bitfields.f1 == 0x1111);
400 assert(bitfields.f2 == 0x2222);413 assert(bitfields.f2 == 0x2222);
test/cases/struct_contains_null_ptr_itself.zig-1
...@@ -19,4 +19,3 @@ pub const Node = struct {...@@ -19,4 +19,3 @@ pub const Node = struct {
19pub const NodeLineComment = struct {19pub const NodeLineComment = struct {
20 base: Node,20 base: Node,
21};21};
22
test/cases/struct_contains_slice_of_itself.zig+1-1
...@@ -6,7 +6,7 @@ const Node = struct {...@@ -6,7 +6,7 @@ const Node = struct {
6};6};
77
8test "struct contains slice of itself" {8test "struct contains slice of itself" {
9 var other_nodes = []Node{9 var other_nodes = []Node {
10 Node {10 Node {
11 .payload = 31,11 .payload = 31,
12 .children = []Node{},12 .children = []Node{},
test/cases/switch.zig+33-16
...@@ -6,7 +6,10 @@ test "switch with numbers" {...@@ -6,7 +6,10 @@ test "switch with numbers" {
66
7fn testSwitchWithNumbers(x: u32) void {7fn testSwitchWithNumbers(x: u32) void {
8 const result = switch (x) {8 const result = switch (x) {
9 1, 2, 3, 4 ... 8 => false,9 1,
10 2,
11 3,
12 4 ... 8 => false,
10 13 => true,13 13 => true,
11 else => false,14 else => false,
12 };15 };
...@@ -34,8 +37,10 @@ test "implicit comptime switch" {...@@ -34,8 +37,10 @@ test "implicit comptime switch" {
34 const result = switch (x) {37 const result = switch (x) {
35 3 => 10,38 3 => 10,
36 4 => 11,39 4 => 11,
37 5, 6 => 12,40 5,
38 7, 8 => 13,41 6 => 12,
42 7,
43 8 => 13,
39 else => 14,44 else => 14,
40 };45 };
4146
...@@ -61,7 +66,6 @@ fn nonConstSwitchOnEnum(fruit: Fruit) void {...@@ -61,7 +66,6 @@ fn nonConstSwitchOnEnum(fruit: Fruit) void {
61 }66 }
62}67}
6368
64
65test "switch statement" {69test "switch statement" {
66 nonConstSwitch(SwitchStatmentFoo.C);70 nonConstSwitch(SwitchStatmentFoo.C);
67}71}
...@@ -81,11 +85,16 @@ const SwitchStatmentFoo = enum {...@@ -81,11 +85,16 @@ const SwitchStatmentFoo = enum {
81 D,85 D,
82};86};
8387
84
85test "switch prong with variable" {88test "switch prong with variable" {
86 switchProngWithVarFn(SwitchProngWithVarEnum { .One = 13});89 switchProngWithVarFn(SwitchProngWithVarEnum {
87 switchProngWithVarFn(SwitchProngWithVarEnum { .Two = 13.0});90 .One = 13,
88 switchProngWithVarFn(SwitchProngWithVarEnum { .Meh = {}});91 });
92 switchProngWithVarFn(SwitchProngWithVarEnum {
93 .Two = 13.0,
94 });
95 switchProngWithVarFn(SwitchProngWithVarEnum {
96 .Meh = {},
97 });
89}98}
90const SwitchProngWithVarEnum = union(enum) {99const SwitchProngWithVarEnum = union(enum) {
91 One: i32,100 One: i32,
...@@ -93,7 +102,7 @@ const SwitchProngWithVarEnum = union(enum) {...@@ -93,7 +102,7 @@ const SwitchProngWithVarEnum = union(enum) {
93 Meh: void,102 Meh: void,
94};103};
95fn switchProngWithVarFn(a: &const SwitchProngWithVarEnum) void {104fn switchProngWithVarFn(a: &const SwitchProngWithVarEnum) void {
96 switch(*a) {105 switch (a.*) {
97 SwitchProngWithVarEnum.One => |x| {106 SwitchProngWithVarEnum.One => |x| {
98 assert(x == 13);107 assert(x == 13);
99 },108 },
...@@ -112,9 +121,11 @@ test "switch on enum using pointer capture" {...@@ -112,9 +121,11 @@ test "switch on enum using pointer capture" {
112}121}
113122
114fn testSwitchEnumPtrCapture() void {123fn testSwitchEnumPtrCapture() void {
115 var value = SwitchProngWithVarEnum { .One = 1234 };124 var value = SwitchProngWithVarEnum {
125 .One = 1234,
126 };
116 switch (value) {127 switch (value) {
117 SwitchProngWithVarEnum.One => |*x| *x += 1,128 SwitchProngWithVarEnum.One => |*x| x.* += 1,
118 else => unreachable,129 else => unreachable,
119 }130 }
120 switch (value) {131 switch (value) {
...@@ -125,8 +136,12 @@ fn testSwitchEnumPtrCapture() void {...@@ -125,8 +136,12 @@ fn testSwitchEnumPtrCapture() void {
125136
126test "switch with multiple expressions" {137test "switch with multiple expressions" {
127 const x = switch (returnsFive()) {138 const x = switch (returnsFive()) {
128 1, 2, 3 => 1,139 1,
129 4, 5, 6 => 2,140 2,
141 3 => 1,
142 4,
143 5,
144 6 => 2,
130 else => i32(3),145 else => i32(3),
131 };146 };
132 assert(x == 2);147 assert(x == 2);
...@@ -135,14 +150,15 @@ fn returnsFive() i32 {...@@ -135,14 +150,15 @@ fn returnsFive() i32 {
135 return 5;150 return 5;
136}151}
137152
138
139const Number = union(enum) {153const Number = union(enum) {
140 One: u64,154 One: u64,
141 Two: u8,155 Two: u8,
142 Three: f32,156 Three: f32,
143};157};
144158
145const number = Number { .Three = 1.23 };159const number = Number {
160 .Three = 1.23,
161};
146162
147fn returnsFalse() bool {163fn returnsFalse() bool {
148 switch (number) {164 switch (number) {
...@@ -198,7 +214,8 @@ fn testSwitchHandleAllCasesRange(x: u8) u8 {...@@ -198,7 +214,8 @@ fn testSwitchHandleAllCasesRange(x: u8) u8 {
198 return switch (x) {214 return switch (x) {
199 0 ... 100 => u8(0),215 0 ... 100 => u8(0),
200 101 ... 200 => 1,216 101 ... 200 => 1,
201 201, 203 => 2,217 201,
218 203 => 2,
202 202 => 4,219 202 => 4,
203 204 ... 255 => 3,220 204 ... 255 => 3,
204 };221 };
test/cases/switch_prong_err_enum.zig+6-2
...@@ -14,14 +14,18 @@ const FormValue = union(enum) {...@@ -14,14 +14,18 @@ const FormValue = union(enum) {
1414
15fn doThing(form_id: u64) error!FormValue {15fn doThing(form_id: u64) error!FormValue {
16 return switch (form_id) {16 return switch (form_id) {
17 17 => FormValue { .Address = try readOnce() },17 17 => FormValue {
18 .Address = try readOnce(),
19 },
18 else => error.InvalidDebugInfo,20 else => error.InvalidDebugInfo,
19 };21 };
20}22}
2123
22test "switch prong returns error enum" {24test "switch prong returns error enum" {
23 switch (doThing(17) catch unreachable) {25 switch (doThing(17) catch unreachable) {
24 FormValue.Address => |payload| { assert(payload == 1); },26 FormValue.Address => |payload| {
27 assert(payload == 1);
28 },
25 else => unreachable,29 else => unreachable,
26 }30 }
27 assert(read_count == 1);31 assert(read_count == 1);
test/cases/switch_prong_implicit_cast.zig+6-2
...@@ -7,8 +7,12 @@ const FormValue = union(enum) {...@@ -7,8 +7,12 @@ const FormValue = union(enum) {
77
8fn foo(id: u64) !FormValue {8fn foo(id: u64) !FormValue {
9 return switch (id) {9 return switch (id) {
10 2 => FormValue { .Two = true },10 2 => FormValue {
11 1 => FormValue { .One = {} },11 .Two = true,
12 },
13 1 => FormValue {
14 .One = {},
15 },
12 else => return error.Whatever,16 else => return error.Whatever,
13 };17 };
14}18}
test/cases/try.zig+3-5
...@@ -3,14 +3,12 @@ const assert = @import("std").debug.assert;...@@ -3,14 +3,12 @@ const assert = @import("std").debug.assert;
3test "try on error union" {3test "try on error union" {
4 tryOnErrorUnionImpl();4 tryOnErrorUnionImpl();
5 comptime tryOnErrorUnionImpl();5 comptime tryOnErrorUnionImpl();
6
7}6}
87
9fn tryOnErrorUnionImpl() void {8fn tryOnErrorUnionImpl() void {
10 const x = if (returnsTen()) |val|9 const x = if (returnsTen()) |val| val + 1 else |err| switch (err) {
11 val + 110 error.ItBroke,
12 else |err| switch (err) {11 error.NoMem => 1,
13 error.ItBroke, error.NoMem => 1,
14 error.CrappedOut => i32(2),12 error.CrappedOut => i32(2),
15 else => unreachable,13 else => unreachable,
16 };14 };
test/cases/undefined.zig+2-2
...@@ -63,6 +63,6 @@ test "assign undefined to struct with method" {...@@ -63,6 +63,6 @@ test "assign undefined to struct with method" {
63}63}
6464
65test "type name of undefined" {65test "type name of undefined" {
66 const x = undefined;66 const x = undefined;
67 assert(mem.eql(u8, @typeName(@typeOf(x)), "(undefined)"));67 assert(mem.eql(u8, @typeName(@typeOf(x)), "(undefined)"));
68}68}
test/cases/union.zig+50-37
...@@ -10,38 +10,41 @@ const Agg = struct {...@@ -10,38 +10,41 @@ const Agg = struct {
10 val2: Value,10 val2: Value,
11};11};
1212
13const v1 = Value { .Int = 1234 };13const v1 = Value{ .Int = 1234 };
14const v2 = Value { .Array = []u8{3} ** 9 };14const v2 = Value{ .Array = []u8{3} ** 9 };
1515
16const err = (error!Agg)(Agg {16const err = (error!Agg)(Agg{
17 .val1 = v1,17 .val1 = v1,
18 .val2 = v2,18 .val2 = v2,
19});19});
2020
21const array = []Value { v1, v2, v1, v2};21const array = []Value{
2222 v1,
23 v2,
24 v1,
25 v2,
26};
2327
24test "unions embedded in aggregate types" {28test "unions embedded in aggregate types" {
25 switch (array[1]) {29 switch (array[1]) {
26 Value.Array => |arr| assert(arr[4] == 3),30 Value.Array => |arr| assert(arr[4] == 3),
27 else => unreachable,31 else => unreachable,
28 }32 }
29 switch((err catch unreachable).val1) {33 switch ((err catch unreachable).val1) {
30 Value.Int => |x| assert(x == 1234),34 Value.Int => |x| assert(x == 1234),
31 else => unreachable,35 else => unreachable,
32 }36 }
33}37}
3438
35
36const Foo = union {39const Foo = union {
37 float: f64,40 float: f64,
38 int: i32,41 int: i32,
39};42};
4043
41test "basic unions" {44test "basic unions" {
42 var foo = Foo { .int = 1 };45 var foo = Foo{ .int = 1 };
43 assert(foo.int == 1);46 assert(foo.int == 1);
44 foo = Foo {.float = 12.34};47 foo = Foo{ .float = 12.34 };
45 assert(foo.float == 12.34);48 assert(foo.float == 12.34);
46}49}
4750
...@@ -56,11 +59,11 @@ test "init union with runtime value" {...@@ -56,11 +59,11 @@ test "init union with runtime value" {
56}59}
5760
58fn setFloat(foo: &Foo, x: f64) void {61fn setFloat(foo: &Foo, x: f64) void {
59 *foo = Foo { .float = x };62 foo.* = Foo{ .float = x };
60}63}
6164
62fn setInt(foo: &Foo, x: i32) void {65fn setInt(foo: &Foo, x: i32) void {
63 *foo = Foo { .int = x };66 foo.* = Foo{ .int = x };
64}67}
6568
66const FooExtern = extern union {69const FooExtern = extern union {
...@@ -69,13 +72,12 @@ const FooExtern = extern union {...@@ -69,13 +72,12 @@ const FooExtern = extern union {
69};72};
7073
71test "basic extern unions" {74test "basic extern unions" {
72 var foo = FooExtern { .int = 1 };75 var foo = FooExtern{ .int = 1 };
73 assert(foo.int == 1);76 assert(foo.int == 1);
74 foo.float = 12.34;77 foo.float = 12.34;
75 assert(foo.float == 12.34);78 assert(foo.float == 12.34);
76}79}
7780
78
79const Letter = enum {81const Letter = enum {
80 A,82 A,
81 B,83 B,
...@@ -93,12 +95,12 @@ test "union with specified enum tag" {...@@ -93,12 +95,12 @@ test "union with specified enum tag" {
93}95}
9496
95fn doTest() void {97fn doTest() void {
96 assert(bar(Payload {.A = 1234}) == -10);98 assert(bar(Payload{ .A = 1234 }) == -10);
97}99}
98100
99fn bar(value: &const Payload) i32 {101fn bar(value: &const Payload) i32 {
100 assert(Letter(*value) == Letter.A);102 assert(Letter(value.*) == Letter.A);
101 return switch (*value) {103 return switch (value.*) {
102 Payload.A => |x| return x - 1244,104 Payload.A => |x| return x - 1244,
103 Payload.B => |x| if (x == 12.34) i32(20) else 21,105 Payload.B => |x| if (x == 12.34) i32(20) else 21,
104 Payload.C => |x| if (x) i32(30) else 31,106 Payload.C => |x| if (x) i32(30) else 31,
...@@ -131,13 +133,13 @@ const MultipleChoice2 = union(enum(u32)) {...@@ -131,13 +133,13 @@ const MultipleChoice2 = union(enum(u32)) {
131133
132test "union(enum(u32)) with specified and unspecified tag values" {134test "union(enum(u32)) with specified and unspecified tag values" {
133 comptime assert(@TagType(@TagType(MultipleChoice2)) == u32);135 comptime assert(@TagType(@TagType(MultipleChoice2)) == u32);
134 testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2 {.C = 123});136 testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2{ .C = 123 });
135 comptime testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2 { .C = 123} );137 comptime testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2{ .C = 123 });
136}138}
137139
138fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: &const MultipleChoice2) void {140fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: &const MultipleChoice2) void {
139 assert(u32(@TagType(MultipleChoice2)(*x)) == 60);141 assert(u32(@TagType(MultipleChoice2)(x.*)) == 60);
140 assert(1123 == switch (*x) {142 assert(1123 == switch (x.*) {
141 MultipleChoice2.A => 1,143 MultipleChoice2.A => 1,
142 MultipleChoice2.B => 2,144 MultipleChoice2.B => 2,
143 MultipleChoice2.C => |v| i32(1000) + v,145 MultipleChoice2.C => |v| i32(1000) + v,
...@@ -150,10 +152,9 @@ fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: &const MultipleChoice2) void...@@ -150,10 +152,9 @@ fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: &const MultipleChoice2) void
150 });152 });
151}153}
152154
153
154const ExternPtrOrInt = extern union {155const ExternPtrOrInt = extern union {
155 ptr: &u8,156 ptr: &u8,
156 int: u64157 int: u64,
157};158};
158test "extern union size" {159test "extern union size" {
159 comptime assert(@sizeOf(ExternPtrOrInt) == 8);160 comptime assert(@sizeOf(ExternPtrOrInt) == 8);
...@@ -161,7 +162,7 @@ test "extern union size" {...@@ -161,7 +162,7 @@ test "extern union size" {
161162
162const PackedPtrOrInt = packed union {163const PackedPtrOrInt = packed union {
163 ptr: &u8,164 ptr: &u8,
164 int: u64165 int: u64,
165};166};
166test "extern union size" {167test "extern union size" {
167 comptime assert(@sizeOf(PackedPtrOrInt) == 8);168 comptime assert(@sizeOf(PackedPtrOrInt) == 8);
...@@ -174,8 +175,16 @@ test "union with only 1 field which is void should be zero bits" {...@@ -174,8 +175,16 @@ test "union with only 1 field which is void should be zero bits" {
174 comptime assert(@sizeOf(ZeroBits) == 0);175 comptime assert(@sizeOf(ZeroBits) == 0);
175}176}
176177
177const TheTag = enum {A, B, C};178const TheTag = enum {
178const TheUnion = union(TheTag) { A: i32, B: i32, C: i32 };179 A,
180 B,
181 C,
182};
183const TheUnion = union(TheTag) {
184 A: i32,
185 B: i32,
186 C: i32,
187};
179test "union field access gives the enum values" {188test "union field access gives the enum values" {
180 assert(TheUnion.A == TheTag.A);189 assert(TheUnion.A == TheTag.A);
181 assert(TheUnion.B == TheTag.B);190 assert(TheUnion.B == TheTag.B);
...@@ -183,20 +192,28 @@ test "union field access gives the enum values" {...@@ -183,20 +192,28 @@ test "union field access gives the enum values" {
183}192}
184193
185test "cast union to tag type of union" {194test "cast union to tag type of union" {
186 testCastUnionToTagType(TheUnion {.B = 1234});195 testCastUnionToTagType(TheUnion{ .B = 1234 });
187 comptime testCastUnionToTagType(TheUnion {.B = 1234});196 comptime testCastUnionToTagType(TheUnion{ .B = 1234 });
188}197}
189198
190fn testCastUnionToTagType(x: &const TheUnion) void {199fn testCastUnionToTagType(x: &const TheUnion) void {
191 assert(TheTag(*x) == TheTag.B);200 assert(TheTag(x.*) == TheTag.B);
192}201}
193202
194test "cast tag type of union to union" {203test "cast tag type of union to union" {
195 var x: Value2 = Letter2.B;204 var x: Value2 = Letter2.B;
196 assert(Letter2(x) == Letter2.B);205 assert(Letter2(x) == Letter2.B);
197}206}
198const Letter2 = enum { A, B, C };207const Letter2 = enum {
199const Value2 = union(Letter2) { A: i32, B, C, };208 A,
209 B,
210 C,
211};
212const Value2 = union(Letter2) {
213 A: i32,
214 B,
215 C,
216};
200217
201test "implicit cast union to its tag type" {218test "implicit cast union to its tag type" {
202 var x: Value2 = Letter2.B;219 var x: Value2 = Letter2.B;
...@@ -217,19 +234,16 @@ const TheUnion2 = union(enum) {...@@ -217,19 +234,16 @@ const TheUnion2 = union(enum) {
217};234};
218235
219fn assertIsTheUnion2Item1(value: &const TheUnion2) void {236fn assertIsTheUnion2Item1(value: &const TheUnion2) void {
220 assert(*value == TheUnion2.Item1);237 assert(value.* == TheUnion2.Item1);
221}238}
222239
223
224pub const PackThis = union(enum) {240pub const PackThis = union(enum) {
225 Invalid: bool,241 Invalid: bool,
226 StringLiteral: u2,242 StringLiteral: u2,
227};243};
228244
229test "constant packed union" {245test "constant packed union" {
230 testConstPackedUnion([]PackThis {246 testConstPackedUnion([]PackThis{PackThis{ .StringLiteral = 1 }});
231 PackThis { .StringLiteral = 1 },
232 });
233}247}
234248
235fn testConstPackedUnion(expected_tokens: []const PackThis) void {249fn testConstPackedUnion(expected_tokens: []const PackThis) void {
...@@ -242,7 +256,7 @@ test "switch on union with only 1 field" {...@@ -242,7 +256,7 @@ test "switch on union with only 1 field" {
242 switch (r) {256 switch (r) {
243 PartialInst.Compiled => {257 PartialInst.Compiled => {
244 var z: PartialInstWithPayload = undefined;258 var z: PartialInstWithPayload = undefined;
245 z = PartialInstWithPayload { .Compiled = 1234 };259 z = PartialInstWithPayload{ .Compiled = 1234 };
246 switch (z) {260 switch (z) {
247 PartialInstWithPayload.Compiled => |x| {261 PartialInstWithPayload.Compiled => |x| {
248 assert(x == 1234);262 assert(x == 1234);
...@@ -261,4 +275,3 @@ const PartialInst = union(enum) {...@@ -261,4 +275,3 @@ const PartialInst = union(enum) {
261const PartialInstWithPayload = union(enum) {275const PartialInstWithPayload = union(enum) {
262 Compiled: i32,276 Compiled: i32,
263};277};
264
test/cases/var_args.zig+16-9
...@@ -2,9 +2,12 @@ const assert = @import("std").debug.assert;...@@ -2,9 +2,12 @@ const assert = @import("std").debug.assert;
22
3fn add(args: ...) i32 {3fn add(args: ...) i32 {
4 var sum = i32(0);4 var sum = i32(0);
5 {comptime var i: usize = 0; inline while (i < args.len) : (i += 1) {5 {
6 sum += args[i];6 comptime var i: usize = 0;
7 }}7 inline while (i < args.len) : (i += 1) {
8 sum += args[i];
9 }
10 }
8 return sum;11 return sum;
9}12}
1013
...@@ -55,18 +58,23 @@ fn extraFn(extra: u32, args: ...) usize {...@@ -55,18 +58,23 @@ fn extraFn(extra: u32, args: ...) usize {
55 return args.len;58 return args.len;
56}59}
5760
61const foos = []fn(...) bool {
62 foo1,
63 foo2,
64};
5865
59const foos = []fn(...) bool { foo1, foo2 };66fn foo1(args: ...) bool {
6067 return true;
61fn foo1(args: ...) bool { return true; }68}
62fn foo2(args: ...) bool { return false; }69fn foo2(args: ...) bool {
70 return false;
71}
6372
64test "array of var args functions" {73test "array of var args functions" {
65 assert(foos[0]());74 assert(foos[0]());
66 assert(!foos[1]());75 assert(!foos[1]());
67}76}
6877
69
70test "pass array and slice of same array to var args should have same pointers" {78test "pass array and slice of same array to var args should have same pointers" {
71 const array = "hi";79 const array = "hi";
72 const slice: []const u8 = array;80 const slice: []const u8 = array;
...@@ -79,7 +87,6 @@ fn assertSlicePtrsEql(args: ...) void {...@@ -79,7 +87,6 @@ fn assertSlicePtrsEql(args: ...) void {
79 assert(s1.ptr == s2.ptr);87 assert(s1.ptr == s2.ptr);
80}88}
8189
82
83test "pass zero length array to var args param" {90test "pass zero length array to var args param" {
84 doNothingWithFirstArg("");91 doNothingWithFirstArg("");
85}92}
test/cases/while.zig+41-24
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const assert = @import("std").debug.assert;1const assert = @import("std").debug.assert;
22
3test "while loop" {3test "while loop" {
4 var i : i32 = 0;4 var i: i32 = 0;
5 while (i < 4) {5 while (i < 4) {
6 i += 1;6 i += 1;
7 }7 }
...@@ -35,7 +35,7 @@ test "continue and break" {...@@ -35,7 +35,7 @@ test "continue and break" {
35}35}
36var continue_and_break_counter: i32 = 0;36var continue_and_break_counter: i32 = 0;
37fn runContinueAndBreakTest() void {37fn runContinueAndBreakTest() void {
38 var i : i32 = 0;38 var i: i32 = 0;
39 while (true) {39 while (true) {
40 continue_and_break_counter += 2;40 continue_and_break_counter += 2;
41 i += 1;41 i += 1;
...@@ -58,10 +58,13 @@ fn returnWithImplicitCastFromWhileLoopTest() error!void {...@@ -58,10 +58,13 @@ fn returnWithImplicitCastFromWhileLoopTest() error!void {
5858
59test "while with continue expression" {59test "while with continue expression" {
60 var sum: i32 = 0;60 var sum: i32 = 0;
61 {var i: i32 = 0; while (i < 10) : (i += 1) {61 {
62 if (i == 5) continue;62 var i: i32 = 0;
63 sum += i;63 while (i < 10) : (i += 1) {
64 }}64 if (i == 5) continue;
65 sum += i;
66 }
67 }
65 assert(sum == 40);68 assert(sum == 40);
66}69}
6770
...@@ -117,17 +120,13 @@ test "while with error union condition" {...@@ -117,17 +120,13 @@ test "while with error union condition" {
117120
118var numbers_left: i32 = undefined;121var numbers_left: i32 = undefined;
119fn getNumberOrErr() error!i32 {122fn getNumberOrErr() error!i32 {
120 return if (numbers_left == 0)123 return if (numbers_left == 0) error.OutOfNumbers else x: {
121 error.OutOfNumbers
122 else x: {
123 numbers_left -= 1;124 numbers_left -= 1;
124 break :x numbers_left;125 break :x numbers_left;
125 };126 };
126}127}
127fn getNumberOrNull() ?i32 {128fn getNumberOrNull() ?i32 {
128 return if (numbers_left == 0)129 return if (numbers_left == 0) null else x: {
129 null
130 else x: {
131 numbers_left -= 1;130 numbers_left -= 1;
132 break :x numbers_left;131 break :x numbers_left;
133 };132 };
...@@ -136,42 +135,48 @@ fn getNumberOrNull() ?i32 {...@@ -136,42 +135,48 @@ fn getNumberOrNull() ?i32 {
136test "while on nullable with else result follow else prong" {135test "while on nullable with else result follow else prong" {
137 const result = while (returnNull()) |value| {136 const result = while (returnNull()) |value| {
138 break value;137 break value;
139 } else i32(2);138 } else
139 i32(2);
140 assert(result == 2);140 assert(result == 2);
141}141}
142142
143test "while on nullable with else result follow break prong" {143test "while on nullable with else result follow break prong" {
144 const result = while (returnMaybe(10)) |value| {144 const result = while (returnMaybe(10)) |value| {
145 break value;145 break value;
146 } else i32(2);146 } else
147 i32(2);
147 assert(result == 10);148 assert(result == 10);
148}149}
149150
150test "while on error union with else result follow else prong" {151test "while on error union with else result follow else prong" {
151 const result = while (returnError()) |value| {152 const result = while (returnError()) |value| {
152 break value;153 break value;
153 } else |err| i32(2);154 } else|err|
155 i32(2);
154 assert(result == 2);156 assert(result == 2);
155}157}
156158
157test "while on error union with else result follow break prong" {159test "while on error union with else result follow break prong" {
158 const result = while (returnSuccess(10)) |value| {160 const result = while (returnSuccess(10)) |value| {
159 break value;161 break value;
160 } else |err| i32(2);162 } else|err|
163 i32(2);
161 assert(result == 10);164 assert(result == 10);
162}165}
163166
164test "while on bool with else result follow else prong" {167test "while on bool with else result follow else prong" {
165 const result = while (returnFalse()) {168 const result = while (returnFalse()) {
166 break i32(10);169 break i32(10);
167 } else i32(2);170 } else
171 i32(2);
168 assert(result == 2);172 assert(result == 2);
169}173}
170174
171test "while on bool with else result follow break prong" {175test "while on bool with else result follow break prong" {
172 const result = while (returnTrue()) {176 const result = while (returnTrue()) {
173 break i32(10);177 break i32(10);
174 } else i32(2);178 } else
179 i32(2);
175 assert(result == 10);180 assert(result == 10);
176}181}
177182
...@@ -202,9 +207,21 @@ fn testContinueOuter() void {...@@ -202,9 +207,21 @@ fn testContinueOuter() void {
202 }207 }
203}208}
204209
205fn returnNull() ?i32 { return null; }210fn returnNull() ?i32 {
206fn returnMaybe(x: i32) ?i32 { return x; }211 return null;
207fn returnError() error!i32 { return error.YouWantedAnError; }212}
208fn returnSuccess(x: i32) error!i32 { return x; }213fn returnMaybe(x: i32) ?i32 {
209fn returnFalse() bool { return false; }214 return x;
210fn returnTrue() bool { return true; }215}
216fn returnError() error!i32 {
217 return error.YouWantedAnError;
218}
219fn returnSuccess(x: i32) error!i32 {
220 return x;
221}
222fn returnFalse() bool {
223 return false;
224}
225fn returnTrue() bool {
226 return true;
227}