| author | |
| committer | |
| log | a35b366eb64272c6d4646aedc035a837ed0c3cb0 |
| tree | dcde18b655e59df2b24f6804eb069f3f43393b28 |
| parent | 76ab1d2b6c9eedd861920ae6b6f8ee06aa482159 |
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 tests49 files changed, 1694 insertions(+), 880 deletions(-)
src/all_types.hpp-1| ... | ... | @@ -614,7 +614,6 @@ enum PrefixOp { |
| 614 | 614 | PrefixOpBinNot, |
| 615 | 615 | PrefixOpNegation, |
| 616 | 616 | PrefixOpNegationWrap, |
| 617 | PrefixOpDereference, | |
| 618 | 617 | PrefixOpMaybe, |
| 619 | 618 | PrefixOpUnwrapMaybe, |
| 620 | 619 | }; |
src/ast_render.cpp-1| ... | ... | @@ -66,7 +66,6 @@ static const char *prefix_op_str(PrefixOp prefix_op) { |
| 66 | 66 | case PrefixOpNegationWrap: return "-%"; |
| 67 | 67 | case PrefixOpBoolNot: return "!"; |
| 68 | 68 | case PrefixOpBinNot: return "~"; |
| 69 | case PrefixOpDereference: return "*"; | |
| 70 | 69 | case PrefixOpMaybe: return "?"; |
| 71 | 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 | 4696 | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegation), lval); |
| 4697 | 4697 | case PrefixOpNegationWrap: |
| 4698 | 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 | 4699 | case PrefixOpMaybe: |
| 4702 | 4700 | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpMaybe), lval); |
| 4703 | 4701 | case PrefixOpUnwrapMaybe: |
src/parser.cpp+1-12| ... | ... | @@ -1165,10 +1165,8 @@ static PrefixOp tok_to_prefix_op(Token *token) { |
| 1165 | 1165 | case TokenIdDash: return PrefixOpNegation; |
| 1166 | 1166 | case TokenIdMinusPercent: return PrefixOpNegationWrap; |
| 1167 | 1167 | case TokenIdTilde: return PrefixOpBinNot; |
| 1168 | case TokenIdStar: return PrefixOpDereference; | |
| 1169 | 1168 | case TokenIdMaybe: return PrefixOpMaybe; |
| 1170 | 1169 | case TokenIdDoubleQuestion: return PrefixOpUnwrapMaybe; |
| 1171 | case TokenIdStarStar: return PrefixOpDereference; | |
| 1172 | 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 | 1212 | |
| 1215 | 1213 | /* |
| 1216 | 1214 | PrefixOpExpression = PrefixOp ErrorSetExpr | SuffixOpExpression |
| 1217 | PrefixOp = "!" | "-" | "~" | "*" | ("&" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "??" | "-%" | "try" | "await" | |
| 1215 | PrefixOp = "!" | "-" | "~" | ("*" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "??" | "-%" | "try" | "await" | |
| 1218 | 1216 | */ |
| 1219 | 1217 | static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory) { |
| 1220 | 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 | 1235 | |
| 1238 | 1236 | AstNode *node = ast_create_node(pc, NodeTypePrefixOpExpr, token); |
| 1239 | 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 | } | |
| 1249 | 1238 | |
| 1250 | 1239 | AstNode *prefix_op_expr = ast_parse_error_set_expr(pc, token_index, true); |
| 1251 | 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 | 247 | return trans_create_node_field_access(c, container, buf_create_from_str(field_name)); |
| 248 | 248 | } |
| 249 | 249 | |
| 250 | static 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 | ||
| 250 | 256 | static AstNode *trans_create_node_prefix_op(Context *c, PrefixOp op, AstNode *child_node) { |
| 251 | 257 | AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr); |
| 252 | 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 | 1418 | AstNode *operation_type_cast = trans_c_cast(c, rhs_location, |
| 1413 | 1419 | stmt->getComputationLHSType(), |
| 1414 | 1420 | stmt->getLHS()->getType(), |
| 1415 | trans_create_node_prefix_op(c, PrefixOpDereference, | |
| 1416 | trans_create_node_symbol(c, tmp_var_name))); | |
| 1421 | trans_create_node_ptr_deref(c, trans_create_node_symbol(c, tmp_var_name))); | |
| 1417 | 1422 | |
| 1418 | 1423 | // result_type(... >> u5(rhs)) |
| 1419 | 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 | 1431 | |
| 1427 | 1432 | // *_ref = ... |
| 1428 | 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 | 1435 | trans_create_node_symbol(c, tmp_var_name)), |
| 1431 | 1436 | BinOpTypeAssign, result_type_cast); |
| 1432 | 1437 | |
| ... | ... | @@ -1436,7 +1441,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result |
| 1436 | 1441 | // break :x *_ref |
| 1437 | 1442 | child_scope->node->data.block.statements.append( |
| 1438 | 1443 | trans_create_node_break(c, label_name, |
| 1439 | trans_create_node_prefix_op(c, PrefixOpDereference, | |
| 1444 | trans_create_node_ptr_deref(c, | |
| 1440 | 1445 | trans_create_node_symbol(c, tmp_var_name)))); |
| 1441 | 1446 | } |
| 1442 | 1447 | |
| ... | ... | @@ -1483,11 +1488,11 @@ static AstNode *trans_create_compound_assign(Context *c, ResultUsed result_used, |
| 1483 | 1488 | if (rhs == nullptr) return nullptr; |
| 1484 | 1489 | |
| 1485 | 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 | 1492 | trans_create_node_symbol(c, tmp_var_name)), |
| 1488 | 1493 | BinOpTypeAssign, |
| 1489 | 1494 | trans_create_node_bin_op(c, |
| 1490 | trans_create_node_prefix_op(c, PrefixOpDereference, | |
| 1495 | trans_create_node_ptr_deref(c, | |
| 1491 | 1496 | trans_create_node_symbol(c, tmp_var_name)), |
| 1492 | 1497 | bin_op, |
| 1493 | 1498 | rhs)); |
| ... | ... | @@ -1496,7 +1501,7 @@ static AstNode *trans_create_compound_assign(Context *c, ResultUsed result_used, |
| 1496 | 1501 | // break :x *_ref |
| 1497 | 1502 | child_scope->node->data.block.statements.append( |
| 1498 | 1503 | trans_create_node_break(c, label_name, |
| 1499 | trans_create_node_prefix_op(c, PrefixOpDereference, | |
| 1504 | trans_create_node_ptr_deref(c, | |
| 1500 | 1505 | trans_create_node_symbol(c, tmp_var_name)))); |
| 1501 | 1506 | |
| 1502 | 1507 | return child_scope->node; |
| ... | ... | @@ -1817,13 +1822,13 @@ static AstNode *trans_create_post_crement(Context *c, ResultUsed result_used, Tr |
| 1817 | 1822 | // const _tmp = *_ref; |
| 1818 | 1823 | Buf* tmp_var_name = buf_create_from_str("_tmp"); |
| 1819 | 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 | 1826 | trans_create_node_symbol(c, ref_var_name))); |
| 1822 | 1827 | child_scope->node->data.block.statements.append(tmp_var_decl); |
| 1823 | 1828 | |
| 1824 | 1829 | // *_ref += 1; |
| 1825 | 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 | 1832 | trans_create_node_symbol(c, ref_var_name)), |
| 1828 | 1833 | assign_op, |
| 1829 | 1834 | trans_create_node_unsigned(c, 1)); |
| ... | ... | @@ -1871,14 +1876,14 @@ static AstNode *trans_create_pre_crement(Context *c, ResultUsed result_used, Tra |
| 1871 | 1876 | |
| 1872 | 1877 | // *_ref += 1; |
| 1873 | 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 | 1880 | trans_create_node_symbol(c, ref_var_name)), |
| 1876 | 1881 | assign_op, |
| 1877 | 1882 | trans_create_node_unsigned(c, 1)); |
| 1878 | 1883 | child_scope->node->data.block.statements.append(assign_statement); |
| 1879 | 1884 | |
| 1880 | 1885 | // 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 | 1887 | trans_create_node_symbol(c, ref_var_name)); |
| 1883 | 1888 | child_scope->node->data.block.statements.append(trans_create_node_break(c, label_name, deref_expr)); |
| 1884 | 1889 | |
| ... | ... | @@ -1923,7 +1928,7 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc |
| 1923 | 1928 | if (is_fn_ptr) |
| 1924 | 1929 | return value_node; |
| 1925 | 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 | 1933 | case UO_Plus: |
| 1929 | 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 | 4474 | } |
| 4470 | 4475 | } |
| 4471 | 4476 | |
| 4472 | static 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 | } | |
| 4481 | 4477 | static AstNode *parse_ctok_prefix_op_expr(Context *c, CTokenize *ctok, size_t *tok_i) { |
| 4482 | 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; | |
| 4488 | 4479 | |
| 4489 | AstNode *prefix_op_expr = parse_ctok_prefix_op_expr(c, ctok, tok_i); | |
| 4490 | if (prefix_op_expr == nullptr) | |
| 4491 | return nullptr; | |
| 4492 | return trans_create_node_prefix_op(c, prefix_op, prefix_op_expr); | |
| 4480 | switch (op_tok->id) { | |
| 4481 | case CTokIdBang: | |
| 4482 | { | |
| 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 | } |
| 4494 | 4517 | |
| 4495 | 4518 | static 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 | 104 | |
| 105 | 105 | var panicking: u8 = 0; // TODO make this a bool |
| 106 | 106 | |
| 107 | pub fn panicExtra(trace: ?&const builtin.StackTrace, first_trace_addr: ?usize, | |
| 108 | comptime format: []const u8, args: ...) noreturn | |
| 109 | { | |
| 107 | pub fn panicExtra(trace: ?&const builtin.StackTrace, first_trace_addr: ?usize, comptime format: []const u8, args: ...) noreturn { | |
| 110 | 108 | @setCold(true); |
| 111 | 109 | |
| 112 | 110 | if (@atomicRmw(u8, &panicking, builtin.AtomicRmwOp.Xchg, 1, builtin.AtomicOrder.SeqCst) == 1) { |
| ... | ... | @@ -132,9 +130,7 @@ const WHITE = "\x1b[37;1m"; |
| 132 | 130 | const DIM = "\x1b[2m"; |
| 133 | 131 | const RESET = "\x1b[0m"; |
| 134 | 132 | |
| 135 | pub fn writeStackTrace(stack_trace: &const builtin.StackTrace, out_stream: var, allocator: &mem.Allocator, | |
| 136 | debug_info: &ElfStackTrace, tty_color: bool) !void | |
| 137 | { | |
| 133 | pub fn writeStackTrace(stack_trace: &const builtin.StackTrace, out_stream: var, allocator: &mem.Allocator, debug_info: &ElfStackTrace, tty_color: bool) !void { | |
| 138 | 134 | var frame_index: usize = undefined; |
| 139 | 135 | var frames_left: usize = undefined; |
| 140 | 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 | 150 | } |
| 155 | 151 | } |
| 156 | 152 | |
| 157 | pub fn writeCurrentStackTrace(out_stream: var, allocator: &mem.Allocator, | |
| 158 | debug_info: &ElfStackTrace, tty_color: bool, start_addr: ?usize) !void | |
| 159 | { | |
| 153 | pub fn writeCurrentStackTrace(out_stream: var, allocator: &mem.Allocator, debug_info: &ElfStackTrace, tty_color: bool, start_addr: ?usize) !void { | |
| 160 | 154 | const AddressState = union(enum) { |
| 161 | 155 | NotLookingForStartAddress, |
| 162 | 156 | LookingForStartAddress: usize, |
| ... | ... | @@ -166,14 +160,14 @@ pub fn writeCurrentStackTrace(out_stream: var, allocator: &mem.Allocator, |
| 166 | 160 | // else AddressState.NotLookingForStartAddress; |
| 167 | 161 | var addr_state: AddressState = undefined; |
| 168 | 162 | if (start_addr) |addr| { |
| 169 | addr_state = AddressState { .LookingForStartAddress = addr }; | |
| 163 | addr_state = AddressState{ .LookingForStartAddress = addr }; | |
| 170 | 164 | } else { |
| 171 | 165 | addr_state = AddressState.NotLookingForStartAddress; |
| 172 | 166 | } |
| 173 | 167 | |
| 174 | 168 | var fp = @ptrToInt(@frameAddress()); |
| 175 | while (fp != 0) : (fp = *@intToPtr(&const usize, fp)) { | |
| 176 | const return_address = *@intToPtr(&const usize, fp + @sizeOf(usize)); | |
| 169 | while (fp != 0) : (fp = @intToPtr(&const usize, fp).*) { | |
| 170 | const return_address = @intToPtr(&const usize, fp + @sizeOf(usize)).*; | |
| 177 | 171 | |
| 178 | 172 | switch (addr_state) { |
| 179 | 173 | AddressState.NotLookingForStartAddress => {}, |
| ... | ... | @@ -200,32 +194,32 @@ fn printSourceAtAddress(debug_info: &ElfStackTrace, out_stream: var, address: us |
| 200 | 194 | // in practice because the compiler dumps everything in a single |
| 201 | 195 | // object file. Future improvement: use external dSYM data when |
| 202 | 196 | // available. |
| 203 | const unknown = macho.Symbol { .name = "???", .address = address }; | |
| 197 | const unknown = macho.Symbol{ | |
| 198 | .name = "???", | |
| 199 | .address = address, | |
| 200 | }; | |
| 204 | 201 | const symbol = debug_info.symbol_table.search(address) ?? &unknown; |
| 205 | try out_stream.print(WHITE ++ "{}" ++ RESET ++ ": " ++ | |
| 206 | DIM ++ ptr_hex ++ " in ??? (???)" ++ RESET ++ "\n", | |
| 207 | symbol.name, address); | |
| 202 | try out_stream.print(WHITE ++ "{}" ++ RESET ++ ": " ++ DIM ++ ptr_hex ++ " in ??? (???)" ++ RESET ++ "\n", symbol.name, address); | |
| 208 | 203 | }, |
| 209 | 204 | else => { |
| 210 | 205 | const compile_unit = findCompileUnit(debug_info, address) catch { |
| 211 | try out_stream.print("???:?:?: " ++ DIM ++ ptr_hex ++ " in ??? (???)" ++ RESET ++ "\n ???\n\n", | |
| 212 | address); | |
| 206 | try out_stream.print("???:?:?: " ++ DIM ++ ptr_hex ++ " in ??? (???)" ++ RESET ++ "\n ???\n\n", address); | |
| 213 | 207 | return; |
| 214 | 208 | }; |
| 215 | 209 | const compile_unit_name = try compile_unit.die.getAttrString(debug_info, DW.AT_name); |
| 216 | 210 | if (getLineNumberInfo(debug_info, compile_unit, address - 1)) |line_info| { |
| 217 | 211 | defer line_info.deinit(); |
| 218 | try out_stream.print(WHITE ++ "{}:{}:{}" ++ RESET ++ ": " ++ | |
| 219 | DIM ++ ptr_hex ++ " in ??? ({})" ++ RESET ++ "\n", | |
| 220 | line_info.file_name, line_info.line, line_info.column, | |
| 221 | address, compile_unit_name); | |
| 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); | |
| 222 | 213 | if (printLineFromFile(debug_info.allocator(), out_stream, line_info)) { |
| 223 | 214 | if (line_info.column == 0) { |
| 224 | 215 | try out_stream.write("\n"); |
| 225 | 216 | } else { |
| 226 | {var col_i: usize = 1; while (col_i < line_info.column) : (col_i += 1) { | |
| 227 | try out_stream.writeByte(' '); | |
| 228 | }} | |
| 217 | { | |
| 218 | var col_i: usize = 1; | |
| 219 | while (col_i < line_info.column) : (col_i += 1) { | |
| 220 | try out_stream.writeByte(' '); | |
| 221 | } | |
| 222 | } | |
| 229 | 223 | try out_stream.write(GREEN ++ "^" ++ RESET ++ "\n"); |
| 230 | 224 | } |
| 231 | 225 | } else |err| switch (err) { |
| ... | ... | @@ -233,7 +227,8 @@ fn printSourceAtAddress(debug_info: &ElfStackTrace, out_stream: var, address: us |
| 233 | 227 | else => return err, |
| 234 | 228 | } |
| 235 | 229 | } else |err| switch (err) { |
| 236 | error.MissingDebugInfo, error.InvalidDebugInfo => { | |
| 230 | error.MissingDebugInfo, | |
| 231 | error.InvalidDebugInfo => { | |
| 237 | 232 | try out_stream.print(ptr_hex ++ " in ??? ({})\n", address, compile_unit_name); |
| 238 | 233 | }, |
| 239 | 234 | else => return err, |
| ... | ... | @@ -247,7 +242,7 @@ pub fn openSelfDebugInfo(allocator: &mem.Allocator) !&ElfStackTrace { |
| 247 | 242 | builtin.ObjectFormat.elf => { |
| 248 | 243 | const st = try allocator.create(ElfStackTrace); |
| 249 | 244 | errdefer allocator.destroy(st); |
| 250 | *st = ElfStackTrace { | |
| 245 | st.* = ElfStackTrace{ | |
| 251 | 246 | .self_exe_file = undefined, |
| 252 | 247 | .elf = undefined, |
| 253 | 248 | .debug_info = undefined, |
| ... | ... | @@ -279,9 +274,7 @@ pub fn openSelfDebugInfo(allocator: &mem.Allocator) !&ElfStackTrace { |
| 279 | 274 | const st = try allocator.create(ElfStackTrace); |
| 280 | 275 | errdefer allocator.destroy(st); |
| 281 | 276 | |
| 282 | *st = ElfStackTrace { | |
| 283 | .symbol_table = try macho.loadSymbols(allocator, &io.FileInStream.init(&exe_file)), | |
| 284 | }; | |
| 277 | st.* = ElfStackTrace{ .symbol_table = try macho.loadSymbols(allocator, &io.FileInStream.init(&exe_file)) }; | |
| 285 | 278 | |
| 286 | 279 | return st; |
| 287 | 280 | }, |
| ... | ... | @@ -325,8 +318,7 @@ fn printLineFromFile(allocator: &mem.Allocator, out_stream: var, line_info: &con |
| 325 | 318 | } |
| 326 | 319 | } |
| 327 | 320 | |
| 328 | if (amt_read < buf.len) | |
| 329 | return error.EndOfFile; | |
| 321 | if (amt_read < buf.len) return error.EndOfFile; | |
| 330 | 322 | } |
| 331 | 323 | } |
| 332 | 324 | |
| ... | ... | @@ -418,10 +410,8 @@ const Constant = struct { |
| 418 | 410 | signed: bool, |
| 419 | 411 | |
| 420 | 412 | fn asUnsignedLe(self: &const Constant) !u64 { |
| 421 | if (self.payload.len > @sizeOf(u64)) | |
| 422 | return error.InvalidDebugInfo; | |
| 423 | if (self.signed) | |
| 424 | return error.InvalidDebugInfo; | |
| 413 | if (self.payload.len > @sizeOf(u64)) return error.InvalidDebugInfo; | |
| 414 | if (self.signed) return error.InvalidDebugInfo; | |
| 425 | 415 | return mem.readInt(self.payload, u64, builtin.Endian.Little); |
| 426 | 416 | } |
| 427 | 417 | }; |
| ... | ... | @@ -438,15 +428,14 @@ const Die = struct { |
| 438 | 428 | |
| 439 | 429 | fn getAttr(self: &const Die, id: u64) ?&const FormValue { |
| 440 | 430 | for (self.attrs.toSliceConst()) |*attr| { |
| 441 | if (attr.id == id) | |
| 442 | return &attr.value; | |
| 431 | if (attr.id == id) return &attr.value; | |
| 443 | 432 | } |
| 444 | 433 | return null; |
| 445 | 434 | } |
| 446 | 435 | |
| 447 | 436 | fn getAttrAddr(self: &const Die, id: u64) !u64 { |
| 448 | 437 | const form_value = self.getAttr(id) ?? return error.MissingDebugInfo; |
| 449 | return switch (*form_value) { | |
| 438 | return switch (form_value.*) { | |
| 450 | 439 | FormValue.Address => |value| value, |
| 451 | 440 | else => error.InvalidDebugInfo, |
| 452 | 441 | }; |
| ... | ... | @@ -454,7 +443,7 @@ const Die = struct { |
| 454 | 443 | |
| 455 | 444 | fn getAttrSecOffset(self: &const Die, id: u64) !u64 { |
| 456 | 445 | const form_value = self.getAttr(id) ?? return error.MissingDebugInfo; |
| 457 | return switch (*form_value) { | |
| 446 | return switch (form_value.*) { | |
| 458 | 447 | FormValue.Const => |value| value.asUnsignedLe(), |
| 459 | 448 | FormValue.SecOffset => |value| value, |
| 460 | 449 | else => error.InvalidDebugInfo, |
| ... | ... | @@ -463,7 +452,7 @@ const Die = struct { |
| 463 | 452 | |
| 464 | 453 | fn getAttrUnsignedLe(self: &const Die, id: u64) !u64 { |
| 465 | 454 | const form_value = self.getAttr(id) ?? return error.MissingDebugInfo; |
| 466 | return switch (*form_value) { | |
| 455 | return switch (form_value.*) { | |
| 467 | 456 | FormValue.Const => |value| value.asUnsignedLe(), |
| 468 | 457 | else => error.InvalidDebugInfo, |
| 469 | 458 | }; |
| ... | ... | @@ -471,7 +460,7 @@ const Die = struct { |
| 471 | 460 | |
| 472 | 461 | fn getAttrString(self: &const Die, st: &ElfStackTrace, id: u64) ![]u8 { |
| 473 | 462 | const form_value = self.getAttr(id) ?? return error.MissingDebugInfo; |
| 474 | return switch (*form_value) { | |
| 463 | return switch (form_value.*) { | |
| 475 | 464 | FormValue.String => |value| value, |
| 476 | 465 | FormValue.StrPtr => |offset| getString(st, offset), |
| 477 | 466 | else => error.InvalidDebugInfo, |
| ... | ... | @@ -518,10 +507,8 @@ const LineNumberProgram = struct { |
| 518 | 507 | prev_basic_block: bool, |
| 519 | 508 | prev_end_sequence: bool, |
| 520 | 509 | |
| 521 | pub fn init(is_stmt: bool, include_dirs: []const []const u8, | |
| 522 | file_entries: &ArrayList(FileEntry), target_address: usize) LineNumberProgram | |
| 523 | { | |
| 524 | return LineNumberProgram { | |
| 510 | pub fn init(is_stmt: bool, include_dirs: []const []const u8, file_entries: &ArrayList(FileEntry), target_address: usize) LineNumberProgram { | |
| 511 | return LineNumberProgram{ | |
| 525 | 512 | .address = 0, |
| 526 | 513 | .file = 1, |
| 527 | 514 | .line = 1, |
| ... | ... | @@ -548,14 +535,16 @@ const LineNumberProgram = struct { |
| 548 | 535 | return error.MissingDebugInfo; |
| 549 | 536 | } else if (self.prev_file - 1 >= self.file_entries.len) { |
| 550 | 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]; | |
| 552 | 540 | |
| 553 | 541 | const dir_name = if (file_entry.dir_index >= self.include_dirs.len) { |
| 554 | 542 | return error.InvalidDebugInfo; |
| 555 | } else self.include_dirs[file_entry.dir_index]; | |
| 543 | } else | |
| 544 | self.include_dirs[file_entry.dir_index]; | |
| 556 | 545 | const file_name = try os.path.join(self.file_entries.allocator, dir_name, file_entry.file_name); |
| 557 | 546 | errdefer self.file_entries.allocator.free(file_name); |
| 558 | return LineInfo { | |
| 547 | return LineInfo{ | |
| 559 | 548 | .line = if (self.prev_line >= 0) usize(self.prev_line) else 0, |
| 560 | 549 | .column = self.prev_column, |
| 561 | 550 | .file_name = file_name, |
| ... | ... | @@ -578,8 +567,7 @@ fn readStringRaw(allocator: &mem.Allocator, in_stream: var) ![]u8 { |
| 578 | 567 | var buf = ArrayList(u8).init(allocator); |
| 579 | 568 | while (true) { |
| 580 | 569 | const byte = try in_stream.readByte(); |
| 581 | if (byte == 0) | |
| 582 | break; | |
| 570 | if (byte == 0) break; | |
| 583 | 571 | try buf.append(byte); |
| 584 | 572 | } |
| 585 | 573 | return buf.toSlice(); |
| ... | ... | @@ -600,7 +588,7 @@ fn readAllocBytes(allocator: &mem.Allocator, in_stream: var, size: usize) ![]u8 |
| 600 | 588 | |
| 601 | 589 | fn parseFormValueBlockLen(allocator: &mem.Allocator, in_stream: var, size: usize) !FormValue { |
| 602 | 590 | const buf = try readAllocBytes(allocator, in_stream, size); |
| 603 | return FormValue { .Block = buf }; | |
| 591 | return FormValue{ .Block = buf }; | |
| 604 | 592 | } |
| 605 | 593 | |
| 606 | 594 | fn 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 | 597 | } |
| 610 | 598 | |
| 611 | 599 | fn parseFormValueConstant(allocator: &mem.Allocator, in_stream: var, signed: bool, size: usize) !FormValue { |
| 612 | return FormValue { .Const = Constant { | |
| 600 | return FormValue{ .Const = Constant{ | |
| 613 | 601 | .signed = signed, |
| 614 | 602 | .payload = try readAllocBytes(allocator, in_stream, size), |
| 615 | }}; | |
| 603 | } }; | |
| 616 | 604 | } |
| 617 | 605 | |
| 618 | 606 | fn parseFormValueDwarfOffsetSize(in_stream: var, is_64: bool) !u64 { |
| 619 | return if (is_64) try in_stream.readIntLe(u64) | |
| 620 | else u64(try in_stream.readIntLe(u32)) ; | |
| 607 | return if (is_64) try in_stream.readIntLe(u64) else u64(try in_stream.readIntLe(u32)); | |
| 621 | 608 | } |
| 622 | 609 | |
| 623 | 610 | fn parseFormValueTargetAddrSize(in_stream: var) !u64 { |
| 624 | return if (@sizeOf(usize) == 4) u64(try in_stream.readIntLe(u32)) | |
| 625 | else if (@sizeOf(usize) == 8) try in_stream.readIntLe(u64) | |
| 626 | else unreachable; | |
| 611 | return if (@sizeOf(usize) == 4) u64(try in_stream.readIntLe(u32)) else if (@sizeOf(usize) == 8) try in_stream.readIntLe(u64) else unreachable; | |
| 627 | 612 | } |
| 628 | 613 | |
| 629 | 614 | fn parseFormValueRefLen(allocator: &mem.Allocator, in_stream: var, size: usize) !FormValue { |
| 630 | 615 | const buf = try readAllocBytes(allocator, in_stream, size); |
| 631 | return FormValue { .Ref = buf }; | |
| 616 | return FormValue{ .Ref = buf }; | |
| 632 | 617 | } |
| 633 | 618 | |
| 634 | 619 | fn parseFormValueRef(allocator: &mem.Allocator, in_stream: var, comptime T: type) !FormValue { |
| ... | ... | @@ -646,11 +631,9 @@ const ParseFormValueError = error { |
| 646 | 631 | OutOfMemory, |
| 647 | 632 | }; |
| 648 | 633 | |
| 649 | fn parseFormValue(allocator: &mem.Allocator, in_stream: var, form_id: u64, is_64: bool) | |
| 650 | ParseFormValueError!FormValue | |
| 651 | { | |
| 634 | fn parseFormValue(allocator: &mem.Allocator, in_stream: var, form_id: u64, is_64: bool) ParseFormValueError!FormValue { | |
| 652 | 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 | 637 | DW.FORM_block1 => parseFormValueBlock(allocator, in_stream, 1), |
| 655 | 638 | DW.FORM_block2 => parseFormValueBlock(allocator, in_stream, 2), |
| 656 | 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 | 645 | DW.FORM_data2 => parseFormValueConstant(allocator, in_stream, false, 2), |
| 663 | 646 | DW.FORM_data4 => parseFormValueConstant(allocator, in_stream, false, 4), |
| 664 | 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 | 650 | const block_len = try readULeb128(in_stream); |
| 667 | 651 | const signed = form_id == DW.FORM_sdata; |
| 668 | 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 | 654 | DW.FORM_exprloc => { |
| 671 | 655 | const size = try readULeb128(in_stream); |
| 672 | 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 }, | |
| 676 | DW.FORM_flag_present => FormValue { .Flag = true }, | |
| 677 | DW.FORM_sec_offset => FormValue { .SecOffset = try parseFormValueDwarfOffsetSize(in_stream, is_64) }, | |
| 659 | DW.FORM_flag => FormValue{ .Flag = (try in_stream.readByte()) != 0 }, | |
| 660 | DW.FORM_flag_present => FormValue{ .Flag = true }, | |
| 661 | DW.FORM_sec_offset => FormValue{ .SecOffset = try parseFormValueDwarfOffsetSize(in_stream, is_64) }, | |
| 678 | 662 | |
| 679 | 663 | DW.FORM_ref1 => parseFormValueRef(allocator, in_stream, u8), |
| 680 | 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 | 669 | return parseFormValueRefLen(allocator, in_stream, ref_len); |
| 686 | 670 | }, |
| 687 | 671 | |
| 688 | DW.FORM_ref_addr => FormValue { .RefAddr = try parseFormValueDwarfOffsetSize(in_stream, is_64) }, | |
| 689 | DW.FORM_ref_sig8 => FormValue { .RefSig8 = try in_stream.readIntLe(u64) }, | |
| 672 | DW.FORM_ref_addr => FormValue{ .RefAddr = try parseFormValueDwarfOffsetSize(in_stream, is_64) }, | |
| 673 | DW.FORM_ref_sig8 => FormValue{ .RefSig8 = try in_stream.readIntLe(u64) }, | |
| 690 | 674 | |
| 691 | DW.FORM_string => FormValue { .String = try readStringRaw(allocator, in_stream) }, | |
| 692 | DW.FORM_strp => FormValue { .StrPtr = try parseFormValueDwarfOffsetSize(in_stream, is_64) }, | |
| 675 | DW.FORM_string => FormValue{ .String = try readStringRaw(allocator, in_stream) }, | |
| 676 | DW.FORM_strp => FormValue{ .StrPtr = try parseFormValueDwarfOffsetSize(in_stream, is_64) }, | |
| 693 | 677 | DW.FORM_indirect => { |
| 694 | 678 | const child_form_id = try readULeb128(in_stream); |
| 695 | 679 | return parseFormValue(allocator, in_stream, child_form_id, is_64); |
| ... | ... | @@ -705,9 +689,8 @@ fn parseAbbrevTable(st: &ElfStackTrace) !AbbrevTable { |
| 705 | 689 | var result = AbbrevTable.init(st.allocator()); |
| 706 | 690 | while (true) { |
| 707 | 691 | const abbrev_code = try readULeb128(in_stream); |
| 708 | if (abbrev_code == 0) | |
| 709 | return result; | |
| 710 | try result.append(AbbrevTableEntry { | |
| 692 | if (abbrev_code == 0) return result; | |
| 693 | try result.append(AbbrevTableEntry{ | |
| 711 | 694 | .abbrev_code = abbrev_code, |
| 712 | 695 | .tag_id = try readULeb128(in_stream), |
| 713 | 696 | .has_children = (try in_stream.readByte()) == DW.CHILDREN_yes, |
| ... | ... | @@ -718,9 +701,8 @@ fn parseAbbrevTable(st: &ElfStackTrace) !AbbrevTable { |
| 718 | 701 | while (true) { |
| 719 | 702 | const attr_id = try readULeb128(in_stream); |
| 720 | 703 | const form_id = try readULeb128(in_stream); |
| 721 | if (attr_id == 0 and form_id == 0) | |
| 722 | break; | |
| 723 | try attrs.append(AbbrevAttr { | |
| 704 | if (attr_id == 0 and form_id == 0) break; | |
| 705 | try attrs.append(AbbrevAttr{ | |
| 724 | 706 | .attr_id = attr_id, |
| 725 | 707 | .form_id = form_id, |
| 726 | 708 | }); |
| ... | ... | @@ -737,7 +719,7 @@ fn getAbbrevTable(st: &ElfStackTrace, abbrev_offset: u64) !&const AbbrevTable { |
| 737 | 719 | } |
| 738 | 720 | } |
| 739 | 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 | 723 | .offset = abbrev_offset, |
| 742 | 724 | .table = try parseAbbrevTable(st), |
| 743 | 725 | }); |
| ... | ... | @@ -746,8 +728,7 @@ fn getAbbrevTable(st: &ElfStackTrace, abbrev_offset: u64) !&const AbbrevTable { |
| 746 | 728 | |
| 747 | 729 | fn getAbbrevTableEntry(abbrev_table: &const AbbrevTable, abbrev_code: u64) ?&const AbbrevTableEntry { |
| 748 | 730 | for (abbrev_table.toSliceConst()) |*table_entry| { |
| 749 | if (table_entry.abbrev_code == abbrev_code) | |
| 750 | return table_entry; | |
| 731 | if (table_entry.abbrev_code == abbrev_code) return table_entry; | |
| 751 | 732 | } |
| 752 | 733 | return null; |
| 753 | 734 | } |
| ... | ... | @@ -759,14 +740,14 @@ fn parseDie(st: &ElfStackTrace, abbrev_table: &const AbbrevTable, is_64: bool) ! |
| 759 | 740 | const abbrev_code = try readULeb128(in_stream); |
| 760 | 741 | const table_entry = getAbbrevTableEntry(abbrev_table, abbrev_code) ?? return error.InvalidDebugInfo; |
| 761 | 742 | |
| 762 | var result = Die { | |
| 743 | var result = Die{ | |
| 763 | 744 | .tag_id = table_entry.tag_id, |
| 764 | 745 | .has_children = table_entry.has_children, |
| 765 | 746 | .attrs = ArrayList(Die.Attr).init(st.allocator()), |
| 766 | 747 | }; |
| 767 | 748 | try result.attrs.resize(table_entry.attrs.len); |
| 768 | 749 | for (table_entry.attrs.toSliceConst()) |attr, i| { |
| 769 | result.attrs.items[i] = Die.Attr { | |
| 750 | result.attrs.items[i] = Die.Attr{ | |
| 770 | 751 | .id = attr.attr_id, |
| 771 | 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 | 771 | |
| 791 | 772 | var is_64: bool = undefined; |
| 792 | 773 | const unit_length = try readInitialLength(@typeOf(in_stream.readFn).ReturnType.ErrorSet, in_stream, &is_64); |
| 793 | if (unit_length == 0) | |
| 794 | return error.MissingDebugInfo; | |
| 774 | if (unit_length == 0) return error.MissingDebugInfo; | |
| 795 | 775 | const next_offset = unit_length + (if (is_64) usize(12) else usize(4)); |
| 796 | 776 | |
| 797 | 777 | if (compile_unit.index != this_index) { |
| ... | ... | @@ -803,8 +783,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe |
| 803 | 783 | // TODO support 3 and 5 |
| 804 | 784 | if (version != 2 and version != 4) return error.InvalidDebugInfo; |
| 805 | 785 | |
| 806 | const prologue_length = if (is_64) try in_stream.readInt(st.elf.endian, u64) | |
| 807 | else try in_stream.readInt(st.elf.endian, u32); | |
| 786 | const prologue_length = if (is_64) try in_stream.readInt(st.elf.endian, u64) else try in_stream.readInt(st.elf.endian, u32); | |
| 808 | 787 | const prog_start_offset = (try in_file.getPos()) + prologue_length; |
| 809 | 788 | |
| 810 | 789 | const minimum_instruction_length = try in_stream.readByte(); |
| ... | ... | @@ -819,38 +798,37 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe |
| 819 | 798 | const line_base = try in_stream.readByteSigned(); |
| 820 | 799 | |
| 821 | 800 | const line_range = try in_stream.readByte(); |
| 822 | if (line_range == 0) | |
| 823 | return error.InvalidDebugInfo; | |
| 801 | if (line_range == 0) return error.InvalidDebugInfo; | |
| 824 | 802 | |
| 825 | 803 | const opcode_base = try in_stream.readByte(); |
| 826 | 804 | |
| 827 | 805 | const standard_opcode_lengths = try st.allocator().alloc(u8, opcode_base - 1); |
| 828 | 806 | |
| 829 | {var i: usize = 0; while (i < opcode_base - 1) : (i += 1) { | |
| 830 | standard_opcode_lengths[i] = try in_stream.readByte(); | |
| 831 | }} | |
| 807 | { | |
| 808 | var i: usize = 0; | |
| 809 | while (i < opcode_base - 1) : (i += 1) { | |
| 810 | standard_opcode_lengths[i] = try in_stream.readByte(); | |
| 811 | } | |
| 812 | } | |
| 832 | 813 | |
| 833 | 814 | var include_directories = ArrayList([]u8).init(st.allocator()); |
| 834 | 815 | try include_directories.append(compile_unit_cwd); |
| 835 | 816 | while (true) { |
| 836 | 817 | const dir = try st.readString(); |
| 837 | if (dir.len == 0) | |
| 838 | break; | |
| 818 | if (dir.len == 0) break; | |
| 839 | 819 | try include_directories.append(dir); |
| 840 | 820 | } |
| 841 | 821 | |
| 842 | 822 | var file_entries = ArrayList(FileEntry).init(st.allocator()); |
| 843 | var prog = LineNumberProgram.init(default_is_stmt, include_directories.toSliceConst(), | |
| 844 | &file_entries, target_address); | |
| 823 | var prog = LineNumberProgram.init(default_is_stmt, include_directories.toSliceConst(), &file_entries, target_address); | |
| 845 | 824 | |
| 846 | 825 | while (true) { |
| 847 | 826 | const file_name = try st.readString(); |
| 848 | if (file_name.len == 0) | |
| 849 | break; | |
| 827 | if (file_name.len == 0) break; | |
| 850 | 828 | const dir_index = try readULeb128(in_stream); |
| 851 | 829 | const mtime = try readULeb128(in_stream); |
| 852 | 830 | const len_bytes = try readULeb128(in_stream); |
| 853 | try file_entries.append(FileEntry { | |
| 831 | try file_entries.append(FileEntry{ | |
| 854 | 832 | .file_name = file_name, |
| 855 | 833 | .dir_index = dir_index, |
| 856 | 834 | .mtime = mtime, |
| ... | ... | @@ -866,8 +844,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe |
| 866 | 844 | var sub_op: u8 = undefined; // TODO move this to the correct scope and fix the compiler crash |
| 867 | 845 | if (opcode == DW.LNS_extended_op) { |
| 868 | 846 | const op_size = try readULeb128(in_stream); |
| 869 | if (op_size < 1) | |
| 870 | return error.InvalidDebugInfo; | |
| 847 | if (op_size < 1) return error.InvalidDebugInfo; | |
| 871 | 848 | sub_op = try in_stream.readByte(); |
| 872 | 849 | switch (sub_op) { |
| 873 | 850 | DW.LNE_end_sequence => { |
| ... | ... | @@ -884,7 +861,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe |
| 884 | 861 | const dir_index = try readULeb128(in_stream); |
| 885 | 862 | const mtime = try readULeb128(in_stream); |
| 886 | 863 | const len_bytes = try readULeb128(in_stream); |
| 887 | try file_entries.append(FileEntry { | |
| 864 | try file_entries.append(FileEntry{ | |
| 888 | 865 | .file_name = file_name, |
| 889 | 866 | .dir_index = dir_index, |
| 890 | 867 | .mtime = mtime, |
| ... | ... | @@ -941,11 +918,9 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe |
| 941 | 918 | const arg = try in_stream.readInt(st.elf.endian, u16); |
| 942 | 919 | prog.address += arg; |
| 943 | 920 | }, |
| 944 | DW.LNS_set_prologue_end => { | |
| 945 | }, | |
| 921 | DW.LNS_set_prologue_end => {}, | |
| 946 | 922 | else => { |
| 947 | if (opcode - 1 >= standard_opcode_lengths.len) | |
| 948 | return error.InvalidDebugInfo; | |
| 923 | if (opcode - 1 >= standard_opcode_lengths.len) return error.InvalidDebugInfo; | |
| 949 | 924 | const len_bytes = standard_opcode_lengths[opcode - 1]; |
| 950 | 925 | try in_file.seekForward(len_bytes); |
| 951 | 926 | }, |
| ... | ... | @@ -972,16 +947,13 @@ fn scanAllCompileUnits(st: &ElfStackTrace) !void { |
| 972 | 947 | |
| 973 | 948 | var is_64: bool = undefined; |
| 974 | 949 | const unit_length = try readInitialLength(@typeOf(in_stream.readFn).ReturnType.ErrorSet, in_stream, &is_64); |
| 975 | if (unit_length == 0) | |
| 976 | return; | |
| 950 | if (unit_length == 0) return; | |
| 977 | 951 | const next_offset = unit_length + (if (is_64) usize(12) else usize(4)); |
| 978 | 952 | |
| 979 | 953 | const version = try in_stream.readInt(st.elf.endian, u16); |
| 980 | 954 | if (version < 2 or version > 5) return error.InvalidDebugInfo; |
| 981 | 955 | |
| 982 | const debug_abbrev_offset = | |
| 983 | if (is_64) try in_stream.readInt(st.elf.endian, u64) | |
| 984 | else try in_stream.readInt(st.elf.endian, u32); | |
| 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); | |
| 985 | 957 | |
| 986 | 958 | const address_size = try in_stream.readByte(); |
| 987 | 959 | if (address_size != @sizeOf(usize)) return error.InvalidDebugInfo; |
| ... | ... | @@ -992,15 +964,14 @@ fn scanAllCompileUnits(st: &ElfStackTrace) !void { |
| 992 | 964 | try st.self_exe_file.seekTo(compile_unit_pos); |
| 993 | 965 | |
| 994 | 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); | |
| 996 | 968 | |
| 997 | if (compile_unit_die.tag_id != DW.TAG_compile_unit) | |
| 998 | return error.InvalidDebugInfo; | |
| 969 | if (compile_unit_die.tag_id != DW.TAG_compile_unit) return error.InvalidDebugInfo; | |
| 999 | 970 | |
| 1000 | 971 | const pc_range = x: { |
| 1001 | 972 | if (compile_unit_die.getAttrAddr(DW.AT_low_pc)) |low_pc| { |
| 1002 | 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 | 975 | FormValue.Address => |value| value, |
| 1005 | 976 | FormValue.Const => |value| b: { |
| 1006 | 977 | const offset = try value.asUnsignedLe(); |
| ... | ... | @@ -1008,7 +979,7 @@ fn scanAllCompileUnits(st: &ElfStackTrace) !void { |
| 1008 | 979 | }, |
| 1009 | 980 | else => return error.InvalidDebugInfo, |
| 1010 | 981 | }; |
| 1011 | break :x PcRange { | |
| 982 | break :x PcRange{ | |
| 1012 | 983 | .start = low_pc, |
| 1013 | 984 | .end = pc_end, |
| 1014 | 985 | }; |
| ... | ... | @@ -1016,13 +987,12 @@ fn scanAllCompileUnits(st: &ElfStackTrace) !void { |
| 1016 | 987 | break :x null; |
| 1017 | 988 | } |
| 1018 | 989 | } else |err| { |
| 1019 | if (err != error.MissingDebugInfo) | |
| 1020 | return err; | |
| 990 | if (err != error.MissingDebugInfo) return err; | |
| 1021 | 991 | break :x null; |
| 1022 | 992 | } |
| 1023 | 993 | }; |
| 1024 | 994 | |
| 1025 | try st.compile_unit_list.append(CompileUnit { | |
| 995 | try st.compile_unit_list.append(CompileUnit{ | |
| 1026 | 996 | .version = version, |
| 1027 | 997 | .is_64 = is_64, |
| 1028 | 998 | .pc_range = pc_range, |
| ... | ... | @@ -1040,8 +1010,7 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) !&const CompileUnit |
| 1040 | 1010 | const in_stream = &in_file_stream.stream; |
| 1041 | 1011 | for (st.compile_unit_list.toSlice()) |*compile_unit| { |
| 1042 | 1012 | if (compile_unit.pc_range) |range| { |
| 1043 | if (target_address >= range.start and target_address < range.end) | |
| 1044 | return compile_unit; | |
| 1013 | if (target_address >= range.start and target_address < range.end) return compile_unit; | |
| 1045 | 1014 | } |
| 1046 | 1015 | if (compile_unit.die.getAttrSecOffset(DW.AT_ranges)) |ranges_offset| { |
| 1047 | 1016 | var base_address: usize = 0; |
| ... | ... | @@ -1063,8 +1032,7 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) !&const CompileUnit |
| 1063 | 1032 | } |
| 1064 | 1033 | } |
| 1065 | 1034 | } else |err| { |
| 1066 | if (err != error.MissingDebugInfo) | |
| 1067 | return err; | |
| 1035 | if (err != error.MissingDebugInfo) return err; | |
| 1068 | 1036 | continue; |
| 1069 | 1037 | } |
| 1070 | 1038 | } |
| ... | ... | @@ -1073,8 +1041,8 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) !&const CompileUnit |
| 1073 | 1041 | |
| 1074 | 1042 | fn readInitialLength(comptime E: type, in_stream: &io.InStream(E), is_64: &bool) !u64 { |
| 1075 | 1043 | const first_32_bits = try in_stream.readIntLe(u32); |
| 1076 | *is_64 = (first_32_bits == 0xffffffff); | |
| 1077 | if (*is_64) { | |
| 1044 | is_64.* = (first_32_bits == 0xffffffff); | |
| 1045 | if (is_64.*) { | |
| 1078 | 1046 | return in_stream.readIntLe(u64); |
| 1079 | 1047 | } else { |
| 1080 | 1048 | if (first_32_bits >= 0xfffffff0) return error.InvalidDebugInfo; |
| ... | ... | @@ -1091,13 +1059,11 @@ fn readULeb128(in_stream: var) !u64 { |
| 1091 | 1059 | |
| 1092 | 1060 | var operand: u64 = undefined; |
| 1093 | 1061 | |
| 1094 | if (@shlWithOverflow(u64, byte & 0b01111111, u6(shift), &operand)) | |
| 1095 | return error.InvalidDebugInfo; | |
| 1062 | if (@shlWithOverflow(u64, byte & 0b01111111, u6(shift), &operand)) return error.InvalidDebugInfo; | |
| 1096 | 1063 | |
| 1097 | 1064 | result |= operand; |
| 1098 | 1065 | |
| 1099 | if ((byte & 0b10000000) == 0) | |
| 1100 | return result; | |
| 1066 | if ((byte & 0b10000000) == 0) return result; | |
| 1101 | 1067 | |
| 1102 | 1068 | shift += 7; |
| 1103 | 1069 | } |
| ... | ... | @@ -1112,15 +1078,13 @@ fn readILeb128(in_stream: var) !i64 { |
| 1112 | 1078 | |
| 1113 | 1079 | var operand: i64 = undefined; |
| 1114 | 1080 | |
| 1115 | if (@shlWithOverflow(i64, byte & 0b01111111, u6(shift), &operand)) | |
| 1116 | return error.InvalidDebugInfo; | |
| 1081 | if (@shlWithOverflow(i64, byte & 0b01111111, u6(shift), &operand)) return error.InvalidDebugInfo; | |
| 1117 | 1082 | |
| 1118 | 1083 | result |= operand; |
| 1119 | 1084 | shift += 7; |
| 1120 | 1085 | |
| 1121 | 1086 | if ((byte & 0b10000000) == 0) { |
| 1122 | if (shift < @sizeOf(i64) * 8 and (byte & 0b01000000) != 0) | |
| 1123 | result |= -(i64(1) << u6(shift)); | |
| 1087 | if (shift < @sizeOf(i64) * 8 and (byte & 0b01000000) != 0) result |= -(i64(1) << u6(shift)); | |
| 1124 | 1088 | return result; |
| 1125 | 1089 | } |
| 1126 | 1090 | } |
| ... | ... | @@ -1131,7 +1095,6 @@ pub const global_allocator = &global_fixed_allocator.allocator; |
| 1131 | 1095 | var global_fixed_allocator = std.heap.FixedBufferAllocator.init(global_allocator_mem[0..]); |
| 1132 | 1096 | var global_allocator_mem: [100 * 1024]u8 = undefined; |
| 1133 | 1097 | |
| 1134 | ||
| 1135 | 1098 | // TODO make thread safe |
| 1136 | 1099 | var debug_info_allocator: ?&mem.Allocator = null; |
| 1137 | 1100 | var 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 | 47 | f32 => { |
| 48 | 48 | var x: f32 = undefined; |
| 49 | 49 | const p = @ptrCast(&volatile f32, &x); |
| 50 | *p = x; | |
| 50 | p.* = x; | |
| 51 | 51 | }, |
| 52 | 52 | f64 => { |
| 53 | 53 | var x: f64 = undefined; |
| 54 | 54 | const p = @ptrCast(&volatile f64, &x); |
| 55 | *p = x; | |
| 55 | p.* = x; | |
| 56 | 56 | }, |
| 57 | 57 | else => { |
| 58 | 58 | @compileError("forceEval not implemented for " ++ @typeName(T)); |
| ... | ... | @@ -179,7 +179,6 @@ test "math" { |
| 179 | 179 | _ = @import("complex/index.zig"); |
| 180 | 180 | } |
| 181 | 181 | |
| 182 | ||
| 183 | 182 | pub fn min(x: var, y: var) @typeOf(x + y) { |
| 184 | 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 | 279 | } |
| 281 | 280 | |
| 282 | 281 | test "math.rotr" { |
| 283 | assert(rotr(u8, 0b00000001, usize(0)) == 0b00000001); | |
| 284 | assert(rotr(u8, 0b00000001, usize(9)) == 0b10000000); | |
| 285 | assert(rotr(u8, 0b00000001, usize(8)) == 0b00000001); | |
| 286 | assert(rotr(u8, 0b00000001, usize(4)) == 0b00010000); | |
| 282 | assert(rotr(u8, 0b00000001, usize(0)) == 0b00000001); | |
| 283 | assert(rotr(u8, 0b00000001, usize(9)) == 0b10000000); | |
| 284 | assert(rotr(u8, 0b00000001, usize(8)) == 0b00000001); | |
| 285 | assert(rotr(u8, 0b00000001, usize(4)) == 0b00010000); | |
| 287 | 286 | assert(rotr(u8, 0b00000001, isize(-1)) == 0b00000010); |
| 288 | 287 | } |
| 289 | 288 | |
| ... | ... | @@ -299,14 +298,13 @@ pub fn rotl(comptime T: type, x: T, r: var) T { |
| 299 | 298 | } |
| 300 | 299 | |
| 301 | 300 | test "math.rotl" { |
| 302 | assert(rotl(u8, 0b00000001, usize(0)) == 0b00000001); | |
| 303 | assert(rotl(u8, 0b00000001, usize(9)) == 0b00000010); | |
| 304 | assert(rotl(u8, 0b00000001, usize(8)) == 0b00000001); | |
| 305 | assert(rotl(u8, 0b00000001, usize(4)) == 0b00010000); | |
| 301 | assert(rotl(u8, 0b00000001, usize(0)) == 0b00000001); | |
| 302 | assert(rotl(u8, 0b00000001, usize(9)) == 0b00000010); | |
| 303 | assert(rotl(u8, 0b00000001, usize(8)) == 0b00000001); | |
| 304 | assert(rotl(u8, 0b00000001, usize(4)) == 0b00010000); | |
| 306 | 305 | assert(rotl(u8, 0b00000001, isize(-1)) == 0b10000000); |
| 307 | 306 | } |
| 308 | 307 | |
| 309 | ||
| 310 | 308 | pub fn Log2Int(comptime T: type) type { |
| 311 | 309 | return @IntType(false, log2(T.bit_count)); |
| 312 | 310 | } |
| ... | ... | @@ -323,14 +321,14 @@ fn testOverflow() void { |
| 323 | 321 | assert((shlExact(i32, 0b11, 4) catch unreachable) == 0b110000); |
| 324 | 322 | } |
| 325 | 323 | |
| 326 | ||
| 327 | 324 | pub fn absInt(x: var) !@typeOf(x) { |
| 328 | 325 | const T = @typeOf(x); |
| 329 | 326 | comptime assert(@typeId(T) == builtin.TypeId.Int); // must pass an integer to absInt |
| 330 | 327 | 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 | 330 | return error.Overflow; |
| 333 | { | |
| 331 | } else { | |
| 334 | 332 | @setRuntimeSafety(false); |
| 335 | 333 | return if (x < 0) -x else x; |
| 336 | 334 | } |
| ... | ... | @@ -349,10 +347,8 @@ pub const absFloat = @import("fabs.zig").fabs; |
| 349 | 347 | |
| 350 | 348 | pub fn divTrunc(comptime T: type, numerator: T, denominator: T) !T { |
| 351 | 349 | @setRuntimeSafety(false); |
| 352 | if (denominator == 0) | |
| 353 | return error.DivisionByZero; | |
| 354 | if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1) | |
| 355 | return error.Overflow; | |
| 350 | if (denominator == 0) return error.DivisionByZero; | |
| 351 | if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1) return error.Overflow; | |
| 356 | 352 | return @divTrunc(numerator, denominator); |
| 357 | 353 | } |
| 358 | 354 | |
| ... | ... | @@ -372,10 +368,8 @@ fn testDivTrunc() void { |
| 372 | 368 | |
| 373 | 369 | pub fn divFloor(comptime T: type, numerator: T, denominator: T) !T { |
| 374 | 370 | @setRuntimeSafety(false); |
| 375 | if (denominator == 0) | |
| 376 | return error.DivisionByZero; | |
| 377 | if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1) | |
| 378 | return error.Overflow; | |
| 371 | if (denominator == 0) return error.DivisionByZero; | |
| 372 | if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1) return error.Overflow; | |
| 379 | 373 | return @divFloor(numerator, denominator); |
| 380 | 374 | } |
| 381 | 375 | |
| ... | ... | @@ -395,13 +389,10 @@ fn testDivFloor() void { |
| 395 | 389 | |
| 396 | 390 | pub fn divExact(comptime T: type, numerator: T, denominator: T) !T { |
| 397 | 391 | @setRuntimeSafety(false); |
| 398 | if (denominator == 0) | |
| 399 | return error.DivisionByZero; | |
| 400 | if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1) | |
| 401 | return error.Overflow; | |
| 392 | if (denominator == 0) return error.DivisionByZero; | |
| 393 | if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1) return error.Overflow; | |
| 402 | 394 | const result = @divTrunc(numerator, denominator); |
| 403 | if (result * denominator != numerator) | |
| 404 | return error.UnexpectedRemainder; | |
| 395 | if (result * denominator != numerator) return error.UnexpectedRemainder; | |
| 405 | 396 | return result; |
| 406 | 397 | } |
| 407 | 398 | |
| ... | ... | @@ -423,10 +414,8 @@ fn testDivExact() void { |
| 423 | 414 | |
| 424 | 415 | pub fn mod(comptime T: type, numerator: T, denominator: T) !T { |
| 425 | 416 | @setRuntimeSafety(false); |
| 426 | if (denominator == 0) | |
| 427 | return error.DivisionByZero; | |
| 428 | if (denominator < 0) | |
| 429 | return error.NegativeDenominator; | |
| 417 | if (denominator == 0) return error.DivisionByZero; | |
| 418 | if (denominator < 0) return error.NegativeDenominator; | |
| 430 | 419 | return @mod(numerator, denominator); |
| 431 | 420 | } |
| 432 | 421 | |
| ... | ... | @@ -448,10 +437,8 @@ fn testMod() void { |
| 448 | 437 | |
| 449 | 438 | pub fn rem(comptime T: type, numerator: T, denominator: T) !T { |
| 450 | 439 | @setRuntimeSafety(false); |
| 451 | if (denominator == 0) | |
| 452 | return error.DivisionByZero; | |
| 453 | if (denominator < 0) | |
| 454 | return error.NegativeDenominator; | |
| 440 | if (denominator == 0) return error.DivisionByZero; | |
| 441 | if (denominator < 0) return error.NegativeDenominator; | |
| 455 | 442 | return @rem(numerator, denominator); |
| 456 | 443 | } |
| 457 | 444 | |
| ... | ... | @@ -475,8 +462,7 @@ fn testRem() void { |
| 475 | 462 | /// Result is an unsigned integer. |
| 476 | 463 | pub fn absCast(x: var) @IntType(false, @typeOf(x).bit_count) { |
| 477 | 464 | const uint = @IntType(false, @typeOf(x).bit_count); |
| 478 | if (x >= 0) | |
| 479 | return uint(x); | |
| 465 | if (x >= 0) return uint(x); | |
| 480 | 466 | |
| 481 | 467 | return uint(-(x + 1)) + 1; |
| 482 | 468 | } |
| ... | ... | @@ -495,15 +481,12 @@ test "math.absCast" { |
| 495 | 481 | /// Returns the negation of the integer parameter. |
| 496 | 482 | /// Result is a signed integer. |
| 497 | 483 | pub fn negateCast(x: var) !@IntType(true, @typeOf(x).bit_count) { |
| 498 | if (@typeOf(x).is_signed) | |
| 499 | return negate(x); | |
| 484 | if (@typeOf(x).is_signed) return negate(x); | |
| 500 | 485 | |
| 501 | 486 | const int = @IntType(true, @typeOf(x).bit_count); |
| 502 | if (x > -@minValue(int)) | |
| 503 | return error.Overflow; | |
| 487 | if (x > -@minValue(int)) return error.Overflow; | |
| 504 | 488 | |
| 505 | if (x == -@minValue(int)) | |
| 506 | return @minValue(int); | |
| 489 | if (x == -@minValue(int)) return @minValue(int); | |
| 507 | 490 | |
| 508 | 491 | return -int(x); |
| 509 | 492 | } |
| ... | ... | @@ -546,7 +529,7 @@ pub fn floorPowerOfTwo(comptime T: type, value: T) T { |
| 546 | 529 | var x = value; |
| 547 | 530 | |
| 548 | 531 | comptime var i = 1; |
| 549 | inline while(T.bit_count > i) : (i *= 2) { | |
| 532 | inline while (T.bit_count > i) : (i *= 2) { | |
| 550 | 533 | x |= (x >> i); |
| 551 | 534 | } |
| 552 | 535 |
std/mem.zig+124-73| ... | ... | @@ -6,14 +6,14 @@ const builtin = @import("builtin"); |
| 6 | 6 | const mem = this; |
| 7 | 7 | |
| 8 | 8 | pub const Allocator = struct { |
| 9 | const Error = error {OutOfMemory}; | |
| 9 | const Error = error{OutOfMemory}; | |
| 10 | 10 | |
| 11 | 11 | /// Allocate byte_count bytes and return them in a slice, with the |
| 12 | 12 | /// slice's pointer aligned at least to alignment bytes. |
| 13 | 13 | /// The returned newly allocated memory is undefined. |
| 14 | 14 | /// `alignment` is guaranteed to be >= 1 |
| 15 | 15 | /// `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, | |
| 17 | 17 | |
| 18 | 18 | /// If `new_byte_count > old_mem.len`: |
| 19 | 19 | /// * `old_mem.len` is the same as what was returned from allocFn or reallocFn. |
| ... | ... | @@ -26,10 +26,10 @@ pub const Allocator = struct { |
| 26 | 26 | /// The returned newly allocated memory is undefined. |
| 27 | 27 | /// `alignment` is guaranteed to be >= 1 |
| 28 | 28 | /// `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, | |
| 30 | 30 | |
| 31 | 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, | |
| 33 | 33 | |
| 34 | 34 | fn create(self: &Allocator, comptime T: type) !&T { |
| 35 | 35 | if (@sizeOf(T) == 0) return &{}; |
| ... | ... | @@ -47,7 +47,7 @@ pub const Allocator = struct { |
| 47 | 47 | if (@sizeOf(T) == 0) return &{}; |
| 48 | 48 | const slice = try self.alloc(T, 1); |
| 49 | 49 | const ptr = &slice[0]; |
| 50 | *ptr = *init; | |
| 50 | ptr.* = init.*; | |
| 51 | 51 | return ptr; |
| 52 | 52 | } |
| 53 | 53 | |
| ... | ... | @@ -59,9 +59,7 @@ pub const Allocator = struct { |
| 59 | 59 | return self.alignedAlloc(T, @alignOf(T), n); |
| 60 | 60 | } |
| 61 | 61 | |
| 62 | fn alignedAlloc(self: &Allocator, comptime T: type, comptime alignment: u29, | |
| 63 | n: usize) ![]align(alignment) T | |
| 64 | { | |
| 62 | fn alignedAlloc(self: &Allocator, comptime T: type, comptime alignment: u29, n: usize) ![]align(alignment) T { | |
| 65 | 63 | if (n == 0) { |
| 66 | 64 | return (&align(alignment) T)(undefined)[0..0]; |
| 67 | 65 | } |
| ... | ... | @@ -70,7 +68,7 @@ pub const Allocator = struct { |
| 70 | 68 | assert(byte_slice.len == byte_count); |
| 71 | 69 | // This loop gets optimized out in ReleaseFast mode |
| 72 | 70 | for (byte_slice) |*byte| { |
| 73 | *byte = undefined; | |
| 71 | byte.* = undefined; | |
| 74 | 72 | } |
| 75 | 73 | return ([]align(alignment) T)(@alignCast(alignment, byte_slice)); |
| 76 | 74 | } |
| ... | ... | @@ -79,9 +77,7 @@ pub const Allocator = struct { |
| 79 | 77 | return self.alignedRealloc(T, @alignOf(T), @alignCast(@alignOf(T), old_mem), n); |
| 80 | 78 | } |
| 81 | 79 | |
| 82 | fn alignedRealloc(self: &Allocator, comptime T: type, comptime alignment: u29, | |
| 83 | old_mem: []align(alignment) T, n: usize) ![]align(alignment) T | |
| 84 | { | |
| 80 | fn alignedRealloc(self: &Allocator, comptime T: type, comptime alignment: u29, old_mem: []align(alignment) T, n: usize) ![]align(alignment) T { | |
| 85 | 81 | if (old_mem.len == 0) { |
| 86 | 82 | return self.alloc(T, n); |
| 87 | 83 | } |
| ... | ... | @@ -97,7 +93,7 @@ pub const Allocator = struct { |
| 97 | 93 | if (n > old_mem.len) { |
| 98 | 94 | // This loop gets optimized out in ReleaseFast mode |
| 99 | 95 | for (byte_slice[old_byte_slice.len..]) |*byte| { |
| 100 | *byte = undefined; | |
| 96 | byte.* = undefined; | |
| 101 | 97 | } |
| 102 | 98 | } |
| 103 | 99 | return ([]T)(@alignCast(alignment, byte_slice)); |
| ... | ... | @@ -110,9 +106,7 @@ pub const Allocator = struct { |
| 110 | 106 | return self.alignedShrink(T, @alignOf(T), @alignCast(@alignOf(T), old_mem), n); |
| 111 | 107 | } |
| 112 | 108 | |
| 113 | fn alignedShrink(self: &Allocator, comptime T: type, comptime alignment: u29, | |
| 114 | old_mem: []align(alignment) T, n: usize) []align(alignment) T | |
| 115 | { | |
| 109 | fn alignedShrink(self: &Allocator, comptime T: type, comptime alignment: u29, old_mem: []align(alignment) T, n: usize) []align(alignment) T { | |
| 116 | 110 | if (n == 0) { |
| 117 | 111 | self.free(old_mem); |
| 118 | 112 | return old_mem[0..0]; |
| ... | ... | @@ -131,8 +125,7 @@ pub const Allocator = struct { |
| 131 | 125 | |
| 132 | 126 | fn free(self: &Allocator, memory: var) void { |
| 133 | 127 | const bytes = ([]const u8)(memory); |
| 134 | if (bytes.len == 0) | |
| 135 | return; | |
| 128 | if (bytes.len == 0) return; | |
| 136 | 129 | const non_const_ptr = @intToPtr(&u8, @ptrToInt(bytes.ptr)); |
| 137 | 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 | 139 | // this and automatically omit safety checks for loops |
| 147 | 140 | @setRuntimeSafety(false); |
| 148 | 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 | } |
| 151 | 145 | |
| 152 | 146 | pub 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 | } |
| 155 | 150 | |
| 156 | 151 | /// Returns true if lhs < rhs, false otherwise |
| ... | ... | @@ -229,8 +224,7 @@ pub fn lastIndexOfScalar(comptime T: type, slice: []const T, value: T) ?usize { |
| 229 | 224 | var i: usize = slice.len; |
| 230 | 225 | while (i != 0) { |
| 231 | 226 | i -= 1; |
| 232 | if (slice[i] == value) | |
| 233 | return i; | |
| 227 | if (slice[i] == value) return i; | |
| 234 | 228 | } |
| 235 | 229 | return null; |
| 236 | 230 | } |
| ... | ... | @@ -238,8 +232,7 @@ pub fn lastIndexOfScalar(comptime T: type, slice: []const T, value: T) ?usize { |
| 238 | 232 | pub fn indexOfScalarPos(comptime T: type, slice: []const T, start_index: usize, value: T) ?usize { |
| 239 | 233 | var i: usize = start_index; |
| 240 | 234 | while (i < slice.len) : (i += 1) { |
| 241 | if (slice[i] == value) | |
| 242 | return i; | |
| 235 | if (slice[i] == value) return i; | |
| 243 | 236 | } |
| 244 | 237 | return null; |
| 245 | 238 | } |
| ... | ... | @@ -253,8 +246,7 @@ pub fn lastIndexOfAny(comptime T: type, slice: []const T, values: []const T) ?us |
| 253 | 246 | while (i != 0) { |
| 254 | 247 | i -= 1; |
| 255 | 248 | for (values) |value| { |
| 256 | if (slice[i] == value) | |
| 257 | return i; | |
| 249 | if (slice[i] == value) return i; | |
| 258 | 250 | } |
| 259 | 251 | } |
| 260 | 252 | return null; |
| ... | ... | @@ -264,8 +256,7 @@ pub fn indexOfAnyPos(comptime T: type, slice: []const T, start_index: usize, val |
| 264 | 256 | var i: usize = start_index; |
| 265 | 257 | while (i < slice.len) : (i += 1) { |
| 266 | 258 | for (values) |value| { |
| 267 | if (slice[i] == value) | |
| 268 | return i; | |
| 259 | if (slice[i] == value) return i; | |
| 269 | 260 | } |
| 270 | 261 | } |
| 271 | 262 | return null; |
| ... | ... | @@ -279,28 +270,23 @@ pub fn indexOf(comptime T: type, haystack: []const T, needle: []const T) ?usize |
| 279 | 270 | /// To start looking at a different index, slice the haystack first. |
| 280 | 271 | /// TODO is there even a better algorithm for this? |
| 281 | 272 | pub fn lastIndexOf(comptime T: type, haystack: []const T, needle: []const T) ?usize { |
| 282 | if (needle.len > haystack.len) | |
| 283 | return null; | |
| 273 | if (needle.len > haystack.len) return null; | |
| 284 | 274 | |
| 285 | 275 | var i: usize = haystack.len - needle.len; |
| 286 | 276 | while (true) : (i -= 1) { |
| 287 | if (mem.eql(T, haystack[i..i+needle.len], needle)) | |
| 288 | return i; | |
| 289 | if (i == 0) | |
| 290 | return null; | |
| 277 | if (mem.eql(T, haystack[i..i + needle.len], needle)) return i; | |
| 278 | if (i == 0) return null; | |
| 291 | 279 | } |
| 292 | 280 | } |
| 293 | 281 | |
| 294 | 282 | // TODO boyer-moore algorithm |
| 295 | 283 | pub fn indexOfPos(comptime T: type, haystack: []const T, start_index: usize, needle: []const T) ?usize { |
| 296 | if (needle.len > haystack.len) | |
| 297 | return null; | |
| 284 | if (needle.len > haystack.len) return null; | |
| 298 | 285 | |
| 299 | 286 | var i: usize = start_index; |
| 300 | 287 | const end = haystack.len - needle.len; |
| 301 | 288 | while (i <= end) : (i += 1) { |
| 302 | if (eql(T, haystack[i .. i + needle.len], needle)) | |
| 303 | return i; | |
| 289 | if (eql(T, haystack[i..i + needle.len], needle)) return i; | |
| 304 | 290 | } |
| 305 | 291 | return null; |
| 306 | 292 | } |
| ... | ... | @@ -355,9 +341,12 @@ pub fn readIntBE(comptime T: type, bytes: []const u8) T { |
| 355 | 341 | } |
| 356 | 342 | assert(bytes.len == @sizeOf(T)); |
| 357 | 343 | var result: T = 0; |
| 358 | {comptime var i = 0; inline while (i < @sizeOf(T)) : (i += 1) { | |
| 359 | result = (result << 8) | T(bytes[i]); | |
| 360 | }} | |
| 344 | { | |
| 345 | comptime var i = 0; | |
| 346 | inline while (i < @sizeOf(T)) : (i += 1) { | |
| 347 | result = (result << 8) | T(bytes[i]); | |
| 348 | } | |
| 349 | } | |
| 361 | 350 | return result; |
| 362 | 351 | } |
| 363 | 352 | |
| ... | ... | @@ -369,9 +358,12 @@ pub fn readIntLE(comptime T: type, bytes: []const u8) T { |
| 369 | 358 | } |
| 370 | 359 | assert(bytes.len == @sizeOf(T)); |
| 371 | 360 | var result: T = 0; |
| 372 | {comptime var i = 0; inline while (i < @sizeOf(T)) : (i += 1) { | |
| 373 | result |= T(bytes[i]) << i * 8; | |
| 374 | }} | |
| 361 | { | |
| 362 | comptime var i = 0; | |
| 363 | inline while (i < @sizeOf(T)) : (i += 1) { | |
| 364 | result |= T(bytes[i]) << i * 8; | |
| 365 | } | |
| 366 | } | |
| 375 | 367 | return result; |
| 376 | 368 | } |
| 377 | 369 | |
| ... | ... | @@ -393,7 +385,7 @@ pub fn writeInt(buf: []u8, value: var, endian: builtin.Endian) void { |
| 393 | 385 | }, |
| 394 | 386 | builtin.Endian.Little => { |
| 395 | 387 | for (buf) |*b| { |
| 396 | *b = @truncate(u8, bits); | |
| 388 | b.* = @truncate(u8, bits); | |
| 397 | 389 | bits >>= 8; |
| 398 | 390 | } |
| 399 | 391 | }, |
| ... | ... | @@ -401,7 +393,6 @@ pub fn writeInt(buf: []u8, value: var, endian: builtin.Endian) void { |
| 401 | 393 | assert(bits == 0); |
| 402 | 394 | } |
| 403 | 395 | |
| 404 | ||
| 405 | 396 | pub fn hash_slice_u8(k: []const u8) u32 { |
| 406 | 397 | // FNV 32-bit hash |
| 407 | 398 | var h: u32 = 2166136261; |
| ... | ... | @@ -420,7 +411,7 @@ pub fn eql_slice_u8(a: []const u8, b: []const u8) bool { |
| 420 | 411 | /// split(" abc def ghi ", " ") |
| 421 | 412 | /// Will return slices for "abc", "def", "ghi", null, in that order. |
| 422 | 413 | pub fn split(buffer: []const u8, split_bytes: []const u8) SplitIterator { |
| 423 | return SplitIterator { | |
| 414 | return SplitIterator{ | |
| 424 | 415 | .index = 0, |
| 425 | 416 | .buffer = buffer, |
| 426 | 417 | .split_bytes = split_bytes, |
| ... | ... | @@ -436,7 +427,7 @@ test "mem.split" { |
| 436 | 427 | } |
| 437 | 428 | |
| 438 | 429 | pub 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 | } |
| 441 | 432 | |
| 442 | 433 | test "mem.startsWith" { |
| ... | ... | @@ -445,10 +436,9 @@ test "mem.startsWith" { |
| 445 | 436 | } |
| 446 | 437 | |
| 447 | 438 | pub 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 | } |
| 450 | 441 | |
| 451 | ||
| 452 | 442 | test "mem.endsWith" { |
| 453 | 443 | assert(endsWith(u8, "Needle in haystack", "haystack")); |
| 454 | 444 | assert(!endsWith(u8, "Bob", "Bo")); |
| ... | ... | @@ -542,29 +532,47 @@ test "testReadInt" { |
| 542 | 532 | } |
| 543 | 533 | fn testReadIntImpl() void { |
| 544 | 534 | { |
| 545 | const bytes = []u8{ 0x12, 0x34, 0x56, 0x78 }; | |
| 546 | assert(readInt(bytes, u32, builtin.Endian.Big) == 0x12345678); | |
| 547 | assert(readIntBE(u32, bytes) == 0x12345678); | |
| 548 | assert(readIntBE(i32, bytes) == 0x12345678); | |
| 535 | const bytes = []u8{ | |
| 536 | 0x12, | |
| 537 | 0x34, | |
| 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 | 544 | assert(readInt(bytes, u32, builtin.Endian.Little) == 0x78563412); |
| 550 | assert(readIntLE(u32, bytes) == 0x78563412); | |
| 551 | assert(readIntLE(i32, bytes) == 0x78563412); | |
| 545 | assert(readIntLE(u32, 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 | 555 | const answer = readInt(buf, u64, builtin.Endian.Big); |
| 556 | 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 | 565 | const answer = readInt(buf, u64, builtin.Endian.Little); |
| 561 | 566 | assert(answer == 0x00003412); |
| 562 | 567 | } |
| 563 | 568 | { |
| 564 | const bytes = []u8{0xff, 0xfe}; | |
| 565 | assert(readIntBE(u16, bytes) == 0xfffe); | |
| 569 | const bytes = []u8{ | |
| 570 | 0xff, | |
| 571 | 0xfe, | |
| 572 | }; | |
| 573 | assert(readIntBE(u16, bytes) == 0xfffe); | |
| 566 | 574 | assert(readIntBE(i16, bytes) == -0x0002); |
| 567 | assert(readIntLE(u16, bytes) == 0xfeff); | |
| 575 | assert(readIntLE(u16, bytes) == 0xfeff); | |
| 568 | 576 | assert(readIntLE(i16, bytes) == -0x0101); |
| 569 | 577 | } |
| 570 | 578 | } |
| ... | ... | @@ -577,19 +585,38 @@ fn testWriteIntImpl() void { |
| 577 | 585 | var bytes: [4]u8 = undefined; |
| 578 | 586 | |
| 579 | 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 | })); | |
| 581 | 594 | |
| 582 | 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 | })); | |
| 584 | 602 | |
| 585 | 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 | })); | |
| 587 | 610 | |
| 588 | 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 | } |
| 591 | 619 | |
| 592 | ||
| 593 | 620 | pub fn min(comptime T: type, slice: []const T) T { |
| 594 | 621 | var best = slice[0]; |
| 595 | 622 | for (slice[1..]) |item| { |
| ... | ... | @@ -615,9 +642,9 @@ test "mem.max" { |
| 615 | 642 | } |
| 616 | 643 | |
| 617 | 644 | pub fn swap(comptime T: type, a: &T, b: &T) void { |
| 618 | const tmp = *a; | |
| 619 | *a = *b; | |
| 620 | *b = tmp; | |
| 645 | const tmp = a.*; | |
| 646 | a.* = b.*; | |
| 647 | b.* = tmp; | |
| 621 | 648 | } |
| 622 | 649 | |
| 623 | 650 | /// In-place order reversal of a slice |
| ... | ... | @@ -630,10 +657,22 @@ pub fn reverse(comptime T: type, items: []T) void { |
| 630 | 657 | } |
| 631 | 658 | |
| 632 | 659 | test "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 | 667 | reverse(i32, arr[0..]); |
| 635 | 668 | |
| 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 | } |
| 638 | 677 | |
| 639 | 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 | 684 | } |
| 646 | 685 | |
| 647 | 686 | test "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 | 694 | rotate(i32, arr[0..], 2); |
| 650 | 695 | |
| 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 | } |
| 653 | 704 | |
| 654 | 705 | // 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 | 3705 | }, |
| 3706 | 3706 | ast.Node.Id.PrefixOp => { |
| 3707 | 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 | 3711 | switch (prefix_op_node.op) { |
| 3710 | 3712 | ast.Node.PrefixOp.Op.AddrOf => |addr_of_info| { |
| 3711 | 3713 | try stream.write("&"); |
| ... | ... | @@ -3742,7 +3744,10 @@ pub const Parser = struct { |
| 3742 | 3744 | }, |
| 3743 | 3745 | ast.Node.PrefixOp.Op.BitNot => try stream.write("~"), |
| 3744 | 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 | 3751 | ast.Node.PrefixOp.Op.Negation => try stream.write("-"), |
| 3747 | 3752 | ast.Node.PrefixOp.Op.NegationWrap => try stream.write("-%"), |
| 3748 | 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 | 10 | assert(@typeOf(slice) == []align(4) u8); |
| 11 | 11 | } |
| 12 | 12 | |
| 13 | fn derp() align(@sizeOf(usize) * 2) i32 { return 1234; } | |
| 13 | fn derp() align(@sizeOf(usize) * 2) i32 { | |
| 14 | return 1234; | |
| 15 | } | |
| 14 | 16 | fn noop1() align(1) void {} |
| 15 | 17 | fn noop4() align(4) void {} |
| 16 | 18 | |
| ... | ... | @@ -22,7 +24,6 @@ test "function alignment" { |
| 22 | 24 | noop4(); |
| 23 | 25 | } |
| 24 | 26 | |
| 25 | ||
| 26 | 27 | var baz: packed struct { |
| 27 | 28 | a: u32, |
| 28 | 29 | b: u32, |
| ... | ... | @@ -32,7 +33,6 @@ test "packed struct alignment" { |
| 32 | 33 | assert(@typeOf(&baz.b) == &align(1) u32); |
| 33 | 34 | } |
| 34 | 35 | |
| 35 | ||
| 36 | 36 | const blah: packed struct { |
| 37 | 37 | a: u3, |
| 38 | 38 | b: u3, |
| ... | ... | @@ -53,29 +53,43 @@ test "implicitly decreasing pointer alignment" { |
| 53 | 53 | assert(addUnaligned(&a, &b) == 7); |
| 54 | 54 | } |
| 55 | 55 | |
| 56 | fn addUnaligned(a: &align(1) const u32, b: &align(1) const u32) u32 { return *a + *b; } | |
| 56 | fn addUnaligned(a: &align(1) const u32, b: &align(1) const u32) u32 { | |
| 57 | return a.* + b.*; | |
| 58 | } | |
| 57 | 59 | |
| 58 | 60 | test "implicitly decreasing slice alignment" { |
| 59 | 61 | const a: u32 align(4) = 3; |
| 60 | 62 | const b: u32 align(8) = 4; |
| 61 | 63 | assert(addUnalignedSlice((&a)[0..1], (&b)[0..1]) == 7); |
| 62 | 64 | } |
| 63 | fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) u32 { return a[0] + b[0]; } | |
| 65 | fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) u32 { | |
| 66 | return a[0] + b[0]; | |
| 67 | } | |
| 64 | 68 | |
| 65 | 69 | test "specifying alignment allows pointer cast" { |
| 66 | 70 | testBytesAlign(0x33); |
| 67 | 71 | } |
| 68 | 72 | fn 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 | 79 | const ptr = @ptrCast(&u32, &bytes[0]); |
| 71 | assert(*ptr == 0x33333333); | |
| 80 | assert(ptr.* == 0x33333333); | |
| 72 | 81 | } |
| 73 | 82 | |
| 74 | 83 | test "specifying alignment allows slice cast" { |
| 75 | 84 | testBytesAlignSlice(0x33); |
| 76 | 85 | } |
| 77 | 86 | fn 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 | 93 | const slice = ([]u32)(bytes[0..]); |
| 80 | 94 | assert(slice[0] == 0x33333333); |
| 81 | 95 | } |
| ... | ... | @@ -89,11 +103,14 @@ fn expectsOnly1(x: &align(1) u32) void { |
| 89 | 103 | expects4(@alignCast(4, x)); |
| 90 | 104 | } |
| 91 | 105 | fn expects4(x: &align(4) u32) void { |
| 92 | *x += 1; | |
| 106 | x.* += 1; | |
| 93 | 107 | } |
| 94 | 108 | |
| 95 | 109 | test "@alignCast slices" { |
| 96 | var array align(4) = []u32{1, 1}; | |
| 110 | var array align(4) = []u32 { | |
| 111 | 1, | |
| 112 | 1, | |
| 113 | }; | |
| 97 | 114 | const slice = array[0..]; |
| 98 | 115 | sliceExpectsOnly1(slice); |
| 99 | 116 | assert(slice[0] == 2); |
| ... | ... | @@ -105,31 +122,34 @@ fn sliceExpects4(slice: []align(4) u32) void { |
| 105 | 122 | slice[0] += 1; |
| 106 | 123 | } |
| 107 | 124 | |
| 108 | ||
| 109 | 125 | test "implicitly decreasing fn alignment" { |
| 110 | 126 | testImplicitlyDecreaseFnAlign(alignedSmall, 1234); |
| 111 | 127 | testImplicitlyDecreaseFnAlign(alignedBig, 5678); |
| 112 | 128 | } |
| 113 | 129 | |
| 114 | fn testImplicitlyDecreaseFnAlign(ptr: fn () align(1) i32, answer: i32) void { | |
| 130 | fn testImplicitlyDecreaseFnAlign(ptr: fn() align(1) i32, answer: i32) void { | |
| 115 | 131 | assert(ptr() == answer); |
| 116 | 132 | } |
| 117 | 133 | |
| 118 | fn alignedSmall() align(8) i32 { return 1234; } | |
| 119 | fn alignedBig() align(16) i32 { return 5678; } | |
| 120 | ||
| 134 | fn alignedSmall() align(8) i32 { | |
| 135 | return 1234; | |
| 136 | } | |
| 137 | fn alignedBig() align(16) i32 { | |
| 138 | return 5678; | |
| 139 | } | |
| 121 | 140 | |
| 122 | 141 | test "@alignCast functions" { |
| 123 | 142 | assert(fnExpectsOnly1(simple4) == 0x19); |
| 124 | 143 | } |
| 125 | fn fnExpectsOnly1(ptr: fn()align(1) i32) i32 { | |
| 144 | fn fnExpectsOnly1(ptr: fn() align(1) i32) i32 { | |
| 126 | 145 | return fnExpects4(@alignCast(4, ptr)); |
| 127 | 146 | } |
| 128 | fn fnExpects4(ptr: fn()align(4) i32) i32 { | |
| 147 | fn fnExpects4(ptr: fn() align(4) i32) i32 { | |
| 129 | 148 | return ptr(); |
| 130 | 149 | } |
| 131 | fn simple4() align(4) i32 { return 0x19; } | |
| 132 | ||
| 150 | fn simple4() align(4) i32 { | |
| 151 | return 0x19; | |
| 152 | } | |
| 133 | 153 | |
| 134 | 154 | test "generic function with align param" { |
| 135 | 155 | assert(whyWouldYouEverDoThis(1) == 0x1); |
| ... | ... | @@ -137,8 +157,9 @@ test "generic function with align param" { |
| 137 | 157 | assert(whyWouldYouEverDoThis(8) == 0x1); |
| 138 | 158 | } |
| 139 | 159 | |
| 140 | fn whyWouldYouEverDoThis(comptime align_bytes: u8) align(align_bytes) u8 { return 0x1; } | |
| 141 | ||
| 160 | fn whyWouldYouEverDoThis(comptime align_bytes: u8) align(align_bytes) u8 { | |
| 161 | return 0x1; | |
| 162 | } | |
| 142 | 163 | |
| 143 | 164 | test "@ptrCast preserves alignment of bigger source" { |
| 144 | 165 | var x: u32 align(16) = 1234; |
| ... | ... | @@ -146,24 +167,38 @@ test "@ptrCast preserves alignment of bigger source" { |
| 146 | 167 | assert(@typeOf(ptr) == &align(16) u8); |
| 147 | 168 | } |
| 148 | 169 | |
| 149 | ||
| 150 | 170 | test "compile-time known array index has best alignment possible" { |
| 151 | 171 | // 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 | 178 | assert(@typeOf(&array[0]) == &align(4) u8); |
| 154 | 179 | assert(@typeOf(&array[1]) == &u8); |
| 155 | 180 | assert(@typeOf(&array[2]) == &align(2) u8); |
| 156 | 181 | assert(@typeOf(&array[3]) == &u8); |
| 157 | 182 | |
| 158 | 183 | // 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 | 190 | assert(@typeOf(&bigger[0]) == &align(2) u64); |
| 161 | 191 | assert(@typeOf(&bigger[1]) == &align(2) u64); |
| 162 | 192 | assert(@typeOf(&bigger[2]) == &align(2) u64); |
| 163 | 193 | assert(@typeOf(&bigger[3]) == &align(2) u64); |
| 164 | 194 | |
| 165 | 195 | // 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 | 202 | testIndex(&smaller[0], 0, &align(2) u32); |
| 168 | 203 | testIndex(&smaller[0], 1, &align(2) u32); |
| 169 | 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 | 217 | assert(@typeOf(&ptr[index]) == T); |
| 183 | 218 | } |
| 184 | 219 | |
| 185 | ||
| 186 | 220 | test "alignstack" { |
| 187 | 221 | assert(fnWithAlignedStack() == 1234); |
| 188 | 222 | } |
test/cases/alignof.zig+5-1| ... | ... | @@ -1,7 +1,11 @@ |
| 1 | 1 | const assert = @import("std").debug.assert; |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | 3 | |
| 4 | const Foo = struct { x: u32, y: u32, z: u32, }; | |
| 4 | const Foo = struct { | |
| 5 | x: u32, | |
| 6 | y: u32, | |
| 7 | z: u32, | |
| 8 | }; | |
| 5 | 9 | |
| 6 | 10 | test "@alignOf(T) before referencing T" { |
| 7 | 11 | comptime assert(@alignOf(Foo) != @maxValue(usize)); |
test/cases/array.zig+31-10| ... | ... | @@ -2,9 +2,9 @@ const assert = @import("std").debug.assert; |
| 2 | 2 | const mem = @import("std").mem; |
| 3 | 3 | |
| 4 | 4 | test "arrays" { |
| 5 | var array : [5]u32 = undefined; | |
| 5 | var array: [5]u32 = undefined; | |
| 6 | 6 | |
| 7 | var i : u32 = 0; | |
| 7 | var i: u32 = 0; | |
| 8 | 8 | while (i < 5) { |
| 9 | 9 | array[i] = i + 1; |
| 10 | 10 | i = array[i]; |
| ... | ... | @@ -34,24 +34,41 @@ test "void arrays" { |
| 34 | 34 | } |
| 35 | 35 | |
| 36 | 36 | test "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 | }; | |
| 38 | 43 | |
| 39 | 44 | assert(hex_mult.len == 4); |
| 40 | 45 | assert(hex_mult[1] == 256); |
| 41 | 46 | } |
| 42 | 47 | |
| 43 | 48 | test "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 | } |
| 46 | 53 | |
| 47 | 54 | const ArrayDotLenConstExpr = struct { |
| 48 | 55 | y: [some_array.len]u8, |
| 49 | 56 | }; |
| 50 | const some_array = []u8 {0, 1, 2, 3}; | |
| 51 | ||
| 57 | const some_array = []u8 { | |
| 58 | 0, | |
| 59 | 1, | |
| 60 | 2, | |
| 61 | 3, | |
| 62 | }; | |
| 52 | 63 | |
| 53 | 64 | test "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 | 72 | for (array_of_strings) |s, i| { |
| 56 | 73 | if (i == 0) assert(mem.eql(u8, s, "hello")); |
| 57 | 74 | if (i == 1) assert(mem.eql(u8, s, "this")); |
| ... | ... | @@ -61,7 +78,6 @@ test "nested arrays" { |
| 61 | 78 | } |
| 62 | 79 | } |
| 63 | 80 | |
| 64 | ||
| 65 | 81 | var s_array: [8]Sub = undefined; |
| 66 | 82 | const Sub = struct { |
| 67 | 83 | b: u8, |
| ... | ... | @@ -70,7 +86,9 @@ const Str = struct { |
| 70 | 86 | a: []Sub, |
| 71 | 87 | }; |
| 72 | 88 | test "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 | }; | |
| 74 | 92 | |
| 75 | 93 | s.a[0].b = 1; |
| 76 | 94 | s.a[1].b = 2; |
| ... | ... | @@ -82,7 +100,10 @@ test "set global var array via slice embedded in struct" { |
| 82 | 100 | } |
| 83 | 101 | |
| 84 | 102 | test "array literal with specified size" { |
| 85 | var array = [2]u8{1, 2}; | |
| 103 | var array = [2]u8 { | |
| 104 | 1, | |
| 105 | 2, | |
| 106 | }; | |
| 86 | 107 | assert(array[0] == 1); |
| 87 | 108 | assert(array[1] == 2); |
| 88 | 109 | } |
test/cases/bitcast.zig+6-2| ... | ... | @@ -10,5 +10,9 @@ fn testBitCast_i32_u32() void { |
| 10 | 10 | assert(conv2(@maxValue(u32)) == -1); |
| 11 | 11 | } |
| 12 | 12 | |
| 13 | fn conv(x: i32) u32 { return @bitCast(u32, x); } | |
| 14 | fn conv2(x: u32) i32 { return @bitCast(i32, x); } | |
| 13 | fn conv(x: i32) u32 { | |
| 14 | return @bitCast(u32, x); | |
| 15 | } | |
| 16 | fn conv2(x: u32) i32 { | |
| 17 | return @bitCast(i32, x); | |
| 18 | } |
test/cases/bugs/394.zig+14-3| ... | ... | @@ -1,9 +1,20 @@ |
| 1 | const E = union(enum) { A: [9]u8, B: u64, }; | |
| 2 | const S = struct { x: u8, y: E, }; | |
| 1 | const E = union(enum) { | |
| 2 | A: [9]u8, | |
| 3 | B: u64, | |
| 4 | }; | |
| 5 | const S = struct { | |
| 6 | x: u8, | |
| 7 | y: E, | |
| 8 | }; | |
| 3 | 9 | |
| 4 | 10 | const assert = @import("std").debug.assert; |
| 5 | 11 | |
| 6 | 12 | test "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 | 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 | 8 | } |
| 9 | 9 | |
| 10 | 10 | fn 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 | 14 | } |
| 15 | 15 | |
| 16 | 16 | fn foo(a: bool, b: bool) void { |
| 17 | var prefix_op = PrefixOp { .AddrOf = Value { .align_expr = 1234 } }; | |
| 18 | if (a) { | |
| 19 | } else { | |
| 17 | var prefix_op = PrefixOp { | |
| 18 | .AddrOf = Value { | |
| 19 | .align_expr = 1234, | |
| 20 | }, | |
| 21 | }; | |
| 22 | if (a) {} else { | |
| 20 | 23 | switch (prefix_op) { |
| 21 | 24 | PrefixOp.AddrOf => |addr_of_info| { |
| 22 | if (b) { } | |
| 25 | if (b) {} | |
| 23 | 26 | if (addr_of_info.align_expr) |align_expr| { |
| 24 | 27 | assert(align_expr == 1234); |
| 25 | 28 | } |
test/cases/bugs/828.zig+5-5| ... | ... | @@ -1,10 +1,10 @@ |
| 1 | 1 | const CountBy = struct { |
| 2 | 2 | a: usize, |
| 3 | ||
| 3 | ||
| 4 | 4 | const One = CountBy { |
| 5 | 5 | .a = 1, |
| 6 | 6 | }; |
| 7 | ||
| 7 | ||
| 8 | 8 | pub fn counter(self: &const CountBy) Counter { |
| 9 | 9 | return Counter { |
| 10 | 10 | .i = 0, |
| ... | ... | @@ -14,7 +14,7 @@ const CountBy = struct { |
| 14 | 14 | |
| 15 | 15 | const Counter = struct { |
| 16 | 16 | i: usize, |
| 17 | ||
| 17 | ||
| 18 | 18 | pub fn count(self: &Counter) bool { |
| 19 | 19 | self.i += 1; |
| 20 | 20 | return self.i <= 10; |
| ... | ... | @@ -24,8 +24,8 @@ const Counter = struct { |
| 24 | 24 | fn constCount(comptime cb: &const CountBy, comptime unused: u32) void { |
| 25 | 25 | comptime { |
| 26 | 26 | var cnt = cb.counter(); |
| 27 | if(cnt.i != 0) @compileError("Counter instance reused!"); | |
| 28 | while(cnt.count()){} | |
| 27 | if (cnt.i != 0) @compileError("Counter instance reused!"); | |
| 28 | while (cnt.count()) {} | |
| 29 | 29 | } |
| 30 | 30 | } |
| 31 | 31 |
test/cases/bugs/920.zig+12-7| ... | ... | @@ -12,8 +12,7 @@ const ZigTable = struct { |
| 12 | 12 | zero_case: fn(&Random, f64) f64, |
| 13 | 13 | }; |
| 14 | 14 | |
| 15 | fn ZigTableGen(comptime is_symmetric: bool, comptime r: f64, comptime v: f64, comptime f: fn(f64) f64, | |
| 16 | comptime f_inv: fn(f64) f64, comptime zero_case: fn(&Random, f64) f64) ZigTable { | |
| 15 | fn 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 { | |
| 17 | 16 | var tables: ZigTable = undefined; |
| 18 | 17 | |
| 19 | 18 | tables.is_symmetric = is_symmetric; |
| ... | ... | @@ -26,12 +25,12 @@ fn ZigTableGen(comptime is_symmetric: bool, comptime r: f64, comptime v: f64, co |
| 26 | 25 | |
| 27 | 26 | for (tables.x[2..256]) |*entry, i| { |
| 28 | 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 | 30 | tables.x[256] = 0; |
| 32 | 31 | |
| 33 | 32 | for (tables.f[0..]) |*entry, i| { |
| 34 | *entry = f(tables.x[i]); | |
| 33 | entry.* = f(tables.x[i]); | |
| 35 | 34 | } |
| 36 | 35 | |
| 37 | 36 | return tables; |
| ... | ... | @@ -40,9 +39,15 @@ fn ZigTableGen(comptime is_symmetric: bool, comptime r: f64, comptime v: f64, co |
| 40 | 39 | const norm_r = 3.6541528853610088; |
| 41 | 40 | const norm_v = 0.00492867323399; |
| 42 | 41 | |
| 43 | fn norm_f(x: f64) f64 { return math.exp(-x * x / 2.0); } | |
| 44 | fn norm_f_inv(y: f64) f64 { return math.sqrt(-2.0 * math.ln(y)); } | |
| 45 | fn norm_zero_case(random: &Random, u: f64) f64 { return 0.0; } | |
| 42 | fn norm_f(x: f64) f64 { | |
| 43 | return math.exp(-x * x / 2.0); | |
| 44 | } | |
| 45 | fn norm_f_inv(y: f64) f64 { | |
| 46 | return math.sqrt(-2.0 * math.ln(y)); | |
| 47 | } | |
| 48 | fn norm_zero_case(random: &Random, u: f64) f64 { | |
| 49 | return 0.0; | |
| 50 | } | |
| 46 | 51 | |
| 47 | 52 | const NormalDist = blk: { |
| 48 | 53 | @setEvalBranchQuota(30000); |
test/cases/cast.zig+43-29| ... | ... | @@ -14,10 +14,10 @@ test "integer literal to pointer cast" { |
| 14 | 14 | } |
| 15 | 15 | |
| 16 | 16 | test "pointer reinterpret const float to int" { |
| 17 | const float: f64 = 5.99999999999994648725e-01; | |
| 17 | const float: f64 = 5.99999999999994648725e - 01; | |
| 18 | 18 | const float_ptr = &float; |
| 19 | 19 | const int_ptr = @ptrCast(&const i32, float_ptr); |
| 20 | const int_val = *int_ptr; | |
| 20 | const int_val = int_ptr.*; | |
| 21 | 21 | assert(int_val == 858993411); |
| 22 | 22 | } |
| 23 | 23 | |
| ... | ... | @@ -29,25 +29,31 @@ test "implicitly cast a pointer to a const pointer of it" { |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | 31 | fn funcWithConstPtrPtr(x: &const &i32) void { |
| 32 | **x += 1; | |
| 32 | x.*.* += 1; | |
| 33 | 33 | } |
| 34 | 34 | |
| 35 | 35 | test "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 | 39 | assert(0 == @sizeOf(@typeOf(z))); |
| 38 | 40 | assert(void{} == Struct(void).pointer(z).x); |
| 39 | 41 | assert(void{} == Struct(void).pointer(&z).x); |
| 40 | 42 | assert(void{} == Struct(void).maybePointer(z).x); |
| 41 | 43 | assert(void{} == Struct(void).maybePointer(&z).x); |
| 42 | 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 | 48 | assert(0 != @sizeOf(@typeOf(s))); |
| 45 | 49 | assert(42 == Struct(u8).pointer(s).x); |
| 46 | 50 | assert(42 == Struct(u8).pointer(&s).x); |
| 47 | 51 | assert(42 == Struct(u8).maybePointer(s).x); |
| 48 | 52 | assert(42 == Struct(u8).maybePointer(&s).x); |
| 49 | 53 | assert(0 == Struct(u8).maybePointer(null).x); |
| 50 | const u = Union { .x = 42 }; | |
| 54 | const u = Union { | |
| 55 | .x = 42, | |
| 56 | }; | |
| 51 | 57 | assert(42 == Union.pointer(u).x); |
| 52 | 58 | assert(42 == Union.pointer(&u).x); |
| 53 | 59 | assert(42 == Union.maybePointer(u).x); |
| ... | ... | @@ -67,12 +73,14 @@ fn Struct(comptime T: type) type { |
| 67 | 73 | x: T, |
| 68 | 74 | |
| 69 | 75 | fn pointer(self: &const Self) Self { |
| 70 | return *self; | |
| 76 | return self.*; | |
| 71 | 77 | } |
| 72 | 78 | |
| 73 | 79 | fn maybePointer(self: ?&const Self) Self { |
| 74 | const none = Self { .x = if (T == void) void{} else 0 }; | |
| 75 | return *(self ?? &none); | |
| 80 | const none = Self { | |
| 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 | 89 | x: u8, |
| 82 | 90 | |
| 83 | 91 | fn pointer(self: &const Union) Union { |
| 84 | return *self; | |
| 92 | return self.*; | |
| 85 | 93 | } |
| 86 | 94 | |
| 87 | 95 | fn maybePointer(self: ?&const Union) Union { |
| 88 | const none = Union { .x = 0 }; | |
| 89 | return *(self ?? &none); | |
| 96 | const none = Union { | |
| 97 | .x = 0, | |
| 98 | }; | |
| 99 | return (self ?? &none).*; | |
| 90 | 100 | } |
| 91 | 101 | }; |
| 92 | 102 | |
| ... | ... | @@ -95,11 +105,11 @@ const Enum = enum { |
| 95 | 105 | Some, |
| 96 | 106 | |
| 97 | 107 | fn pointer(self: &const Enum) Enum { |
| 98 | return *self; | |
| 108 | return self.*; | |
| 99 | 109 | } |
| 100 | 110 | |
| 101 | 111 | fn maybePointer(self: ?&const Enum) Enum { |
| 102 | return *(self ?? &Enum.None); | |
| 112 | return (self ?? &Enum.None).*; | |
| 103 | 113 | } |
| 104 | 114 | }; |
| 105 | 115 | |
| ... | ... | @@ -108,19 +118,21 @@ test "implicitly cast indirect pointer to maybe-indirect pointer" { |
| 108 | 118 | const Self = this; |
| 109 | 119 | x: u8, |
| 110 | 120 | fn constConst(p: &const &const Self) u8 { |
| 111 | return (*p).x; | |
| 121 | return (p.*).x; | |
| 112 | 122 | } |
| 113 | 123 | fn maybeConstConst(p: ?&const &const Self) u8 { |
| 114 | return (*??p).x; | |
| 124 | return (??p.*).x; | |
| 115 | 125 | } |
| 116 | 126 | fn constConstConst(p: &const &const &const Self) u8 { |
| 117 | return (**p).x; | |
| 127 | return (p.*.*).x; | |
| 118 | 128 | } |
| 119 | 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 | 136 | const p = &s; |
| 125 | 137 | const q = &p; |
| 126 | 138 | const r = &q; |
| ... | ... | @@ -154,7 +166,6 @@ fn boolToStr(b: bool) []const u8 { |
| 154 | 166 | return if (b) "true" else "false"; |
| 155 | 167 | } |
| 156 | 168 | |
| 157 | ||
| 158 | 169 | test "peer resolve array and const slice" { |
| 159 | 170 | testPeerResolveArrayConstSlice(true); |
| 160 | 171 | comptime testPeerResolveArrayConstSlice(true); |
| ... | ... | @@ -168,12 +179,12 @@ fn testPeerResolveArrayConstSlice(b: bool) void { |
| 168 | 179 | |
| 169 | 180 | test "integer literal to &const int" { |
| 170 | 181 | const x: &const i32 = 3; |
| 171 | assert(*x == 3); | |
| 182 | assert(x.* == 3); | |
| 172 | 183 | } |
| 173 | 184 | |
| 174 | 185 | test "string literal to &const []const u8" { |
| 175 | 186 | const x: &const []const u8 = "hello"; |
| 176 | assert(mem.eql(u8, *x, "hello")); | |
| 187 | assert(mem.eql(u8, x.*, "hello")); | |
| 177 | 188 | } |
| 178 | 189 | |
| 179 | 190 | test "implicitly cast from T to error!?T" { |
| ... | ... | @@ -191,7 +202,9 @@ fn castToMaybeTypeError(z: i32) void { |
| 191 | 202 | const f = z; |
| 192 | 203 | const g: error!?i32 = f; |
| 193 | 204 | |
| 194 | const a = A{ .a = z }; | |
| 205 | const a = A { | |
| 206 | .a = z, | |
| 207 | }; | |
| 195 | 208 | const b: error!?A = a; |
| 196 | 209 | assert((??(b catch unreachable)).a == 1); |
| 197 | 210 | } |
| ... | ... | @@ -205,7 +218,6 @@ fn implicitIntLitToMaybe() void { |
| 205 | 218 | const g: error!?i32 = 1; |
| 206 | 219 | } |
| 207 | 220 | |
| 208 | ||
| 209 | 221 | test "return null from fn() error!?&T" { |
| 210 | 222 | const a = returnNullFromMaybeTypeErrorRef(); |
| 211 | 223 | const b = returnNullLitFromMaybeTypeErrorRef(); |
| ... | ... | @@ -235,7 +247,6 @@ fn peerTypeTAndMaybeT(c: bool, b: bool) ?usize { |
| 235 | 247 | return usize(3); |
| 236 | 248 | } |
| 237 | 249 | |
| 238 | ||
| 239 | 250 | test "peer type resolution: [0]u8 and []const u8" { |
| 240 | 251 | assert(peerTypeEmptyArrayAndSlice(true, "hi").len == 0); |
| 241 | 252 | assert(peerTypeEmptyArrayAndSlice(false, "hi").len == 1); |
| ... | ... | @@ -246,7 +257,7 @@ test "peer type resolution: [0]u8 and []const u8" { |
| 246 | 257 | } |
| 247 | 258 | fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 { |
| 248 | 259 | if (a) { |
| 249 | return []const u8 {}; | |
| 260 | return []const u8{}; | |
| 250 | 261 | } |
| 251 | 262 | |
| 252 | 263 | return slice[0..1]; |
| ... | ... | @@ -261,7 +272,6 @@ fn castToMaybeSlice() ?[]const u8 { |
| 261 | 272 | return "hi"; |
| 262 | 273 | } |
| 263 | 274 | |
| 264 | ||
| 265 | 275 | test "implicitly cast from [0]T to error![]T" { |
| 266 | 276 | testCastZeroArrayToErrSliceMut(); |
| 267 | 277 | comptime testCastZeroArrayToErrSliceMut(); |
| ... | ... | @@ -329,7 +339,6 @@ fn foo(args: ...) void { |
| 329 | 339 | assert(@typeOf(args[0]) == &const [5]u8); |
| 330 | 340 | } |
| 331 | 341 | |
| 332 | ||
| 333 | 342 | test "peer type resolution: error and [N]T" { |
| 334 | 343 | // TODO: implicit error!T to error!U where T can implicitly cast to U |
| 335 | 344 | //assert(mem.eql(u8, try testPeerErrorAndArray(0), "OK")); |
| ... | ... | @@ -378,7 +387,12 @@ fn cast128Float(x: u128) f128 { |
| 378 | 387 | } |
| 379 | 388 | |
| 380 | 389 | test "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 | }; | |
| 382 | 396 | |
| 383 | 397 | const u32_value = ([]const u32)(bytes[0..])[0]; |
| 384 | 398 | assert(u32_value == 0x12121212); |
test/cases/coroutines.zig+9-9| ... | ... | @@ -36,7 +36,7 @@ async fn testAsyncSeq() void { |
| 36 | 36 | suspend; |
| 37 | 37 | seq('d'); |
| 38 | 38 | } |
| 39 | var points = []u8{0} ** "abcdefg".len; | |
| 39 | var points = []u8 {0} ** "abcdefg".len; | |
| 40 | 40 | var index: usize = 0; |
| 41 | 41 | |
| 42 | 42 | fn seq(c: u8) void { |
| ... | ... | @@ -94,7 +94,7 @@ async fn await_another() i32 { |
| 94 | 94 | return 1234; |
| 95 | 95 | } |
| 96 | 96 | |
| 97 | var await_points = []u8{0} ** "abcdefghi".len; | |
| 97 | var await_points = []u8 {0} ** "abcdefghi".len; | |
| 98 | 98 | var await_seq_index: usize = 0; |
| 99 | 99 | |
| 100 | 100 | fn await_seq(c: u8) void { |
| ... | ... | @@ -102,7 +102,6 @@ fn await_seq(c: u8) void { |
| 102 | 102 | await_seq_index += 1; |
| 103 | 103 | } |
| 104 | 104 | |
| 105 | ||
| 106 | 105 | var early_final_result: i32 = 0; |
| 107 | 106 | |
| 108 | 107 | test "coroutine await early return" { |
| ... | ... | @@ -126,7 +125,7 @@ async fn early_another() i32 { |
| 126 | 125 | return 1234; |
| 127 | 126 | } |
| 128 | 127 | |
| 129 | var early_points = []u8{0} ** "abcdef".len; | |
| 128 | var early_points = []u8 {0} ** "abcdef".len; | |
| 130 | 129 | var early_seq_index: usize = 0; |
| 131 | 130 | |
| 132 | 131 | fn early_seq(c: u8) void { |
| ... | ... | @@ -175,8 +174,8 @@ test "async fn pointer in a struct field" { |
| 175 | 174 | } |
| 176 | 175 | |
| 177 | 176 | async<&std.mem.Allocator> fn simpleAsyncFn2(y: &i32) void { |
| 178 | defer *y += 2; | |
| 179 | *y += 1; | |
| 177 | defer y.* += 2; | |
| 178 | y.* += 1; | |
| 180 | 179 | suspend; |
| 181 | 180 | } |
| 182 | 181 | |
| ... | ... | @@ -205,7 +204,8 @@ test "error return trace across suspend points - async return" { |
| 205 | 204 | cancel p2; |
| 206 | 205 | } |
| 207 | 206 | |
| 208 | fn nonFailing() promise->error!void { | |
| 207 | // TODO https://github.com/zig-lang/zig/issues/760 | |
| 208 | fn nonFailing() (promise->error!void) { | |
| 209 | 209 | return async<std.debug.global_allocator> suspendThenFail() catch unreachable; |
| 210 | 210 | } |
| 211 | 211 | |
| ... | ... | @@ -238,7 +238,7 @@ async fn testBreakFromSuspend(my_result: &i32) void { |
| 238 | 238 | s: suspend |p| { |
| 239 | 239 | break :s; |
| 240 | 240 | } |
| 241 | *my_result += 1; | |
| 241 | my_result.* += 1; | |
| 242 | 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 | 5 | |
| 6 | 6 | fn runSomeErrorDefers(x: bool) !bool { |
| 7 | 7 | index = 0; |
| 8 | defer {result[index] = 'a'; index += 1;} | |
| 9 | errdefer {result[index] = 'b'; index += 1;} | |
| 10 | defer {result[index] = 'c'; index += 1;} | |
| 8 | defer { | |
| 9 | result[index] = 'a'; | |
| 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 | 20 | return if (x) x else error.FalseNotAllowed; |
| 12 | 21 | } |
| 13 | 22 |
test/cases/enum.zig+548-58| ... | ... | @@ -2,8 +2,15 @@ const assert = @import("std").debug.assert; |
| 2 | 2 | const mem = @import("std").mem; |
| 3 | 3 | |
| 4 | 4 | test "enum type" { |
| 5 | const foo1 = Foo{ .One = 13}; | |
| 6 | const foo2 = Foo{. Two = Point { .x = 1234, .y = 5678, }}; | |
| 5 | const foo1 = Foo { | |
| 6 | .One = 13, | |
| 7 | }; | |
| 8 | const foo2 = Foo { | |
| 9 | .Two = Point { | |
| 10 | .x = 1234, | |
| 11 | .y = 5678, | |
| 12 | }, | |
| 13 | }; | |
| 7 | 14 | const bar = Bar.B; |
| 8 | 15 | |
| 9 | 16 | assert(bar == Bar.B); |
| ... | ... | @@ -41,26 +48,31 @@ const Bar = enum { |
| 41 | 48 | }; |
| 42 | 49 | |
| 43 | 50 | fn returnAnInt(x: i32) Foo { |
| 44 | return Foo { .One = x }; | |
| 51 | return Foo { | |
| 52 | .One = x, | |
| 53 | }; | |
| 45 | 54 | } |
| 46 | 55 | |
| 47 | ||
| 48 | 56 | test "constant enum with payload" { |
| 49 | var empty = AnEnumWithPayload {.Empty = {}}; | |
| 50 | var full = AnEnumWithPayload {.Full = 13}; | |
| 57 | var empty = AnEnumWithPayload { | |
| 58 | .Empty = {}, | |
| 59 | }; | |
| 60 | var full = AnEnumWithPayload { | |
| 61 | .Full = 13, | |
| 62 | }; | |
| 51 | 63 | shouldBeEmpty(empty); |
| 52 | 64 | shouldBeNotEmpty(full); |
| 53 | 65 | } |
| 54 | 66 | |
| 55 | 67 | fn shouldBeEmpty(x: &const AnEnumWithPayload) void { |
| 56 | switch (*x) { | |
| 68 | switch (x.*) { | |
| 57 | 69 | AnEnumWithPayload.Empty => {}, |
| 58 | 70 | else => unreachable, |
| 59 | 71 | } |
| 60 | 72 | } |
| 61 | 73 | |
| 62 | 74 | fn shouldBeNotEmpty(x: &const AnEnumWithPayload) void { |
| 63 | switch (*x) { | |
| 75 | switch (x.*) { | |
| 64 | 76 | AnEnumWithPayload.Empty => unreachable, |
| 65 | 77 | else => {}, |
| 66 | 78 | } |
| ... | ... | @@ -71,8 +83,6 @@ const AnEnumWithPayload = union(enum) { |
| 71 | 83 | Full: i32, |
| 72 | 84 | }; |
| 73 | 85 | |
| 74 | ||
| 75 | ||
| 76 | 86 | const Number = enum { |
| 77 | 87 | Zero, |
| 78 | 88 | One, |
| ... | ... | @@ -93,7 +103,6 @@ fn shouldEqual(n: Number, expected: u3) void { |
| 93 | 103 | assert(u3(n) == expected); |
| 94 | 104 | } |
| 95 | 105 | |
| 96 | ||
| 97 | 106 | test "int to enum" { |
| 98 | 107 | testIntToEnumEval(3); |
| 99 | 108 | } |
| ... | ... | @@ -108,7 +117,6 @@ const IntToEnumNumber = enum { |
| 108 | 117 | Four, |
| 109 | 118 | }; |
| 110 | 119 | |
| 111 | ||
| 112 | 120 | test "@tagName" { |
| 113 | 121 | assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three")); |
| 114 | 122 | comptime assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three")); |
| ... | ... | @@ -124,7 +132,6 @@ const BareNumber = enum { |
| 124 | 132 | Three, |
| 125 | 133 | }; |
| 126 | 134 | |
| 127 | ||
| 128 | 135 | test "enum alignment" { |
| 129 | 136 | comptime { |
| 130 | 137 | assert(@alignOf(AlignTestEnum) >= @alignOf([9]u8)); |
| ... | ... | @@ -137,47 +144,529 @@ const AlignTestEnum = union(enum) { |
| 137 | 144 | B: u64, |
| 138 | 145 | }; |
| 139 | 146 | |
| 140 | const ValueCount1 = enum { I0 }; | |
| 141 | const ValueCount2 = enum { I0, I1 }; | |
| 147 | const ValueCount1 = enum { | |
| 148 | I0, | |
| 149 | }; | |
| 150 | const ValueCount2 = enum { | |
| 151 | I0, | |
| 152 | I1, | |
| 153 | }; | |
| 142 | 154 | const ValueCount256 = enum { |
| 143 | I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15, | |
| 144 | I16, I17, I18, I19, I20, I21, I22, I23, I24, I25, I26, I27, I28, I29, I30, I31, | |
| 145 | I32, I33, I34, I35, I36, I37, I38, I39, I40, I41, I42, I43, I44, I45, I46, I47, | |
| 146 | I48, I49, I50, I51, I52, I53, I54, I55, I56, I57, I58, I59, I60, I61, I62, I63, | |
| 147 | I64, I65, I66, I67, I68, I69, I70, I71, I72, I73, I74, I75, I76, I77, I78, I79, | |
| 148 | I80, I81, I82, I83, I84, I85, I86, I87, I88, I89, I90, I91, I92, I93, I94, I95, | |
| 149 | I96, I97, I98, I99, I100, I101, I102, I103, I104, I105, I106, I107, I108, I109, | |
| 150 | I110, I111, I112, I113, I114, I115, I116, I117, I118, I119, I120, I121, I122, I123, | |
| 151 | I124, I125, I126, I127, I128, I129, I130, I131, I132, I133, I134, I135, I136, I137, | |
| 152 | I138, I139, I140, I141, I142, I143, I144, I145, I146, I147, I148, I149, I150, I151, | |
| 153 | I152, I153, I154, I155, I156, I157, I158, I159, I160, I161, I162, I163, I164, I165, | |
| 154 | I166, I167, I168, I169, I170, I171, I172, I173, I174, I175, I176, I177, I178, I179, | |
| 155 | I180, I181, I182, I183, I184, I185, I186, I187, I188, I189, I190, I191, I192, I193, | |
| 156 | I194, I195, I196, I197, I198, I199, I200, I201, I202, I203, I204, I205, I206, I207, | |
| 157 | I208, I209, I210, I211, I212, I213, I214, I215, I216, I217, I218, I219, I220, I221, | |
| 158 | I222, I223, I224, I225, I226, I227, I228, I229, I230, I231, I232, I233, I234, I235, | |
| 159 | I236, I237, I238, I239, I240, I241, I242, I243, I244, I245, I246, I247, I248, I249, | |
| 160 | I250, I251, I252, I253, I254, I255 | |
| 155 | I0, | |
| 156 | I1, | |
| 157 | I2, | |
| 158 | I3, | |
| 159 | I4, | |
| 160 | I5, | |
| 161 | I6, | |
| 162 | I7, | |
| 163 | I8, | |
| 164 | I9, | |
| 165 | I10, | |
| 166 | I11, | |
| 167 | I12, | |
| 168 | I13, | |
| 169 | I14, | |
| 170 | I15, | |
| 171 | I16, | |
| 172 | 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 | }; |
| 162 | 412 | const ValueCount257 = enum { |
| 163 | I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15, | |
| 164 | I16, I17, I18, I19, I20, I21, I22, I23, I24, I25, I26, I27, I28, I29, I30, I31, | |
| 165 | I32, I33, I34, I35, I36, I37, I38, I39, I40, I41, I42, I43, I44, I45, I46, I47, | |
| 166 | I48, I49, I50, I51, I52, I53, I54, I55, I56, I57, I58, I59, I60, I61, I62, I63, | |
| 167 | I64, I65, I66, I67, I68, I69, I70, I71, I72, I73, I74, I75, I76, I77, I78, I79, | |
| 168 | I80, I81, I82, I83, I84, I85, I86, I87, I88, I89, I90, I91, I92, I93, I94, I95, | |
| 169 | I96, I97, I98, I99, I100, I101, I102, I103, I104, I105, I106, I107, I108, I109, | |
| 170 | I110, I111, I112, I113, I114, I115, I116, I117, I118, I119, I120, I121, I122, I123, | |
| 171 | I124, I125, I126, I127, I128, I129, I130, I131, I132, I133, I134, I135, I136, I137, | |
| 172 | I138, I139, I140, I141, I142, I143, I144, I145, I146, I147, I148, I149, I150, I151, | |
| 173 | I152, I153, I154, I155, I156, I157, I158, I159, I160, I161, I162, I163, I164, I165, | |
| 174 | I166, I167, I168, I169, I170, I171, I172, I173, I174, I175, I176, I177, I178, I179, | |
| 175 | I180, I181, I182, I183, I184, I185, I186, I187, I188, I189, I190, I191, I192, I193, | |
| 176 | I194, I195, I196, I197, I198, I199, I200, I201, I202, I203, I204, I205, I206, I207, | |
| 177 | I208, I209, I210, I211, I212, I213, I214, I215, I216, I217, I218, I219, I220, I221, | |
| 178 | I222, I223, I224, I225, I226, I227, I228, I229, I230, I231, I232, I233, I234, I235, | |
| 179 | I236, I237, I238, I239, I240, I241, I242, I243, I244, I245, I246, I247, I248, I249, | |
| 180 | I250, I251, I252, I253, I254, I255, I256 | |
| 413 | I0, | |
| 414 | I1, | |
| 415 | I2, | |
| 416 | I3, | |
| 417 | I4, | |
| 418 | I5, | |
| 419 | I6, | |
| 420 | I7, | |
| 421 | I8, | |
| 422 | I9, | |
| 423 | I10, | |
| 424 | I11, | |
| 425 | I12, | |
| 426 | I13, | |
| 427 | I14, | |
| 428 | I15, | |
| 429 | I16, | |
| 430 | 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 | }; |
| 182 | 671 | |
| 183 | 672 | test "enum sizes" { |
| ... | ... | @@ -189,11 +678,11 @@ test "enum sizes" { |
| 189 | 678 | } |
| 190 | 679 | } |
| 191 | 680 | |
| 192 | const Small2 = enum (u2) { | |
| 681 | const Small2 = enum(u2) { | |
| 193 | 682 | One, |
| 194 | 683 | Two, |
| 195 | 684 | }; |
| 196 | const Small = enum (u2) { | |
| 685 | const Small = enum(u2) { | |
| 197 | 686 | One, |
| 198 | 687 | Two, |
| 199 | 688 | Three, |
| ... | ... | @@ -213,8 +702,7 @@ test "set enum tag type" { |
| 213 | 702 | } |
| 214 | 703 | } |
| 215 | 704 | |
| 216 | ||
| 217 | const A = enum (u3) { | |
| 705 | const A = enum(u3) { | |
| 218 | 706 | One, |
| 219 | 707 | Two, |
| 220 | 708 | Three, |
| ... | ... | @@ -225,7 +713,7 @@ const A = enum (u3) { |
| 225 | 713 | Four2, |
| 226 | 714 | }; |
| 227 | 715 | |
| 228 | const B = enum (u3) { | |
| 716 | const B = enum(u3) { | |
| 229 | 717 | One3, |
| 230 | 718 | Two3, |
| 231 | 719 | Three3, |
| ... | ... | @@ -236,7 +724,7 @@ const B = enum (u3) { |
| 236 | 724 | Four23, |
| 237 | 725 | }; |
| 238 | 726 | |
| 239 | const C = enum (u2) { | |
| 727 | const C = enum(u2) { | |
| 240 | 728 | One4, |
| 241 | 729 | Two4, |
| 242 | 730 | Three4, |
| ... | ... | @@ -389,6 +877,8 @@ test "enum with tag values don't require parens" { |
| 389 | 877 | } |
| 390 | 878 | |
| 391 | 879 | test "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 | 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 | UINT: u32, |
| 8 | 8 | |
| 9 | 9 | pub fn print(a: &const ET, buf: []u8) error!usize { |
| 10 | return switch (*a) { | |
| 10 | return switch (a.*) { | |
| 11 | 11 | ET.SINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0), |
| 12 | 12 | ET.UINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0), |
| 13 | 13 | }; |
| ... | ... | @@ -15,8 +15,12 @@ const ET = union(enum) { |
| 15 | 15 | }; |
| 16 | 16 | |
| 17 | 17 | test "enum with members" { |
| 18 | const a = ET { .SINT = -42 }; | |
| 19 | const b = ET { .UINT = 42 }; | |
| 18 | const a = ET { | |
| 19 | .SINT = -42, | |
| 20 | }; | |
| 21 | const b = ET { | |
| 22 | .UINT = 42, | |
| 23 | }; | |
| 20 | 24 | var buf: [20]u8 = undefined; |
| 21 | 25 | |
| 22 | 26 | assert((a.print(buf[0..]) catch unreachable) == 3); |
test/cases/error.zig+30-26| ... | ... | @@ -30,14 +30,12 @@ test "@errorName" { |
| 30 | 30 | assert(mem.eql(u8, @errorName(error.ALongerErrorName), "ALongerErrorName")); |
| 31 | 31 | } |
| 32 | 32 | |
| 33 | ||
| 34 | 33 | test "error values" { |
| 35 | 34 | const a = i32(error.err1); |
| 36 | 35 | const b = i32(error.err2); |
| 37 | 36 | assert(a != b); |
| 38 | 37 | } |
| 39 | 38 | |
| 40 | ||
| 41 | 39 | test "redefinition of error values allowed" { |
| 42 | 40 | shouldBeNotEqual(error.AnError, error.SecondError); |
| 43 | 41 | } |
| ... | ... | @@ -45,7 +43,6 @@ fn shouldBeNotEqual(a: error, b: error) void { |
| 45 | 43 | if (a == b) unreachable; |
| 46 | 44 | } |
| 47 | 45 | |
| 48 | ||
| 49 | 46 | test "error binary operator" { |
| 50 | 47 | const a = errBinaryOperatorG(true) catch 3; |
| 51 | 48 | const b = errBinaryOperatorG(false) catch 3; |
| ... | ... | @@ -56,20 +53,20 @@ fn errBinaryOperatorG(x: bool) error!isize { |
| 56 | 53 | return if (x) error.ItBroke else isize(10); |
| 57 | 54 | } |
| 58 | 55 | |
| 59 | ||
| 60 | 56 | test "unwrap simple value from error" { |
| 61 | 57 | const i = unwrapSimpleValueFromErrorDo() catch unreachable; |
| 62 | 58 | assert(i == 13); |
| 63 | 59 | } |
| 64 | fn unwrapSimpleValueFromErrorDo() error!isize { return 13; } | |
| 65 | ||
| 60 | fn unwrapSimpleValueFromErrorDo() error!isize { | |
| 61 | return 13; | |
| 62 | } | |
| 66 | 63 | |
| 67 | 64 | test "error return in assignment" { |
| 68 | 65 | doErrReturnInAssignment() catch unreachable; |
| 69 | 66 | } |
| 70 | 67 | |
| 71 | 68 | fn doErrReturnInAssignment() error!void { |
| 72 | var x : i32 = undefined; | |
| 69 | var x: i32 = undefined; | |
| 73 | 70 | x = try makeANonErr(); |
| 74 | 71 | } |
| 75 | 72 | |
| ... | ... | @@ -95,7 +92,10 @@ test "error set type " { |
| 95 | 92 | comptime testErrorSetType(); |
| 96 | 93 | } |
| 97 | 94 | |
| 98 | const MyErrSet = error {OutOfMemory, FileNotFound}; | |
| 95 | const MyErrSet = error { | |
| 96 | OutOfMemory, | |
| 97 | FileNotFound, | |
| 98 | }; | |
| 99 | 99 | |
| 100 | 100 | fn testErrorSetType() void { |
| 101 | 101 | assert(@memberCount(MyErrSet) == 2); |
| ... | ... | @@ -109,14 +109,19 @@ fn testErrorSetType() void { |
| 109 | 109 | } |
| 110 | 110 | } |
| 111 | 111 | |
| 112 | ||
| 113 | 112 | test "explicit error set cast" { |
| 114 | 113 | testExplicitErrorSetCast(Set1.A); |
| 115 | 114 | comptime testExplicitErrorSetCast(Set1.A); |
| 116 | 115 | } |
| 117 | 116 | |
| 118 | const Set1 = error{A, B}; | |
| 119 | const Set2 = error{A, C}; | |
| 117 | const Set1 = error { | |
| 118 | A, | |
| 119 | B, | |
| 120 | }; | |
| 121 | const Set2 = error { | |
| 122 | A, | |
| 123 | C, | |
| 124 | }; | |
| 120 | 125 | |
| 121 | 126 | fn testExplicitErrorSetCast(set1: Set1) void { |
| 122 | 127 | var x = Set2(set1); |
| ... | ... | @@ -129,7 +134,8 @@ test "comptime test error for empty error set" { |
| 129 | 134 | comptime testComptimeTestErrorEmptySet(1234); |
| 130 | 135 | } |
| 131 | 136 | |
| 132 | const EmptyErrorSet = error {}; | |
| 137 | const EmptyErrorSet = error { | |
| 138 | }; | |
| 133 | 139 | |
| 134 | 140 | fn testComptimeTestErrorEmptySet(x: EmptyErrorSet!i32) void { |
| 135 | 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 | 151 | testErrToIntWithOnePossibleValue(error.A, u32(error.A)); |
| 146 | 152 | comptime testErrToIntWithOnePossibleValue(error.A, u32(error.A)); |
| 147 | 153 | } |
| 148 | fn testErrToIntWithOnePossibleValue(x: error{A}, comptime value: u32) void { | |
| 154 | fn testErrToIntWithOnePossibleValue(x: error { | |
| 155 | A, | |
| 156 | }, comptime value: u32) void { | |
| 149 | 157 | if (u32(x) != value) { |
| 150 | 158 | @compileError("bad"); |
| 151 | 159 | } |
| ... | ... | @@ -176,7 +184,6 @@ fn quux_1() !i32 { |
| 176 | 184 | return error.C; |
| 177 | 185 | } |
| 178 | 186 | |
| 179 | ||
| 180 | 187 | test "error: fn returning empty error set can be passed as fn returning any error" { |
| 181 | 188 | entry(); |
| 182 | 189 | comptime entry(); |
| ... | ... | @@ -186,24 +193,24 @@ fn entry() void { |
| 186 | 193 | foo2(bar2); |
| 187 | 194 | } |
| 188 | 195 | |
| 189 | fn foo2(f: fn()error!void) void { | |
| 196 | fn foo2(f: fn() error!void) void { | |
| 190 | 197 | const x = f(); |
| 191 | 198 | } |
| 192 | 199 | |
| 193 | fn bar2() (error{}!void) { } | |
| 194 | ||
| 200 | fn bar2() (error { | |
| 201 | }!void) {} | |
| 195 | 202 | |
| 196 | 203 | test "error: Zero sized error set returned with value payload crash" { |
| 197 | 204 | _ = foo3(0); |
| 198 | 205 | _ = comptime foo3(0); |
| 199 | 206 | } |
| 200 | 207 | |
| 201 | const Error = error{}; | |
| 208 | const Error = error { | |
| 209 | }; | |
| 202 | 210 | fn foo3(b: usize) Error!usize { |
| 203 | 211 | return b; |
| 204 | 212 | } |
| 205 | 213 | |
| 206 | ||
| 207 | 214 | test "error: Infer error set from literals" { |
| 208 | 215 | _ = nullLiteral("n") catch |err| handleErrors(err); |
| 209 | 216 | _ = floatLiteral("n") catch |err| handleErrors(err); |
| ... | ... | @@ -215,29 +222,26 @@ test "error: Infer error set from literals" { |
| 215 | 222 | |
| 216 | 223 | fn handleErrors(err: var) noreturn { |
| 217 | 224 | switch (err) { |
| 218 | error.T => {} | |
| 225 | error.T => {}, | |
| 219 | 226 | } |
| 220 | 227 | |
| 221 | 228 | unreachable; |
| 222 | 229 | } |
| 223 | 230 | |
| 224 | 231 | fn nullLiteral(str: []const u8) !?i64 { |
| 225 | if (str[0] == 'n') | |
| 226 | return null; | |
| 232 | if (str[0] == 'n') return null; | |
| 227 | 233 | |
| 228 | 234 | return error.T; |
| 229 | 235 | } |
| 230 | 236 | |
| 231 | 237 | fn floatLiteral(str: []const u8) !?f64 { |
| 232 | if (str[0] == 'n') | |
| 233 | return 1.0; | |
| 238 | if (str[0] == 'n') return 1.0; | |
| 234 | 239 | |
| 235 | 240 | return error.T; |
| 236 | 241 | } |
| 237 | 242 | |
| 238 | 243 | fn intLiteral(str: []const u8) !?i64 { |
| 239 | if (str[0] == 'n') | |
| 240 | return 1; | |
| 244 | if (str[0] == 'n') return 1; | |
| 241 | 245 | |
| 242 | 246 | return error.T; |
| 243 | 247 | } |
test/cases/eval.zig+88-55| ... | ... | @@ -11,8 +11,6 @@ fn fibonacci(x: i32) i32 { |
| 11 | 11 | return fibonacci(x - 1) + fibonacci(x - 2); |
| 12 | 12 | } |
| 13 | 13 | |
| 14 | ||
| 15 | ||
| 16 | 14 | fn unwrapAndAddOne(blah: ?i32) i32 { |
| 17 | 15 | return ??blah + 1; |
| 18 | 16 | } |
| ... | ... | @@ -40,13 +38,13 @@ test "inline variable gets result of const if" { |
| 40 | 38 | assert(gimme1or2(false) == 2); |
| 41 | 39 | } |
| 42 | 40 | |
| 43 | ||
| 44 | 41 | test "static function evaluation" { |
| 45 | 42 | assert(statically_added_number == 3); |
| 46 | 43 | } |
| 47 | 44 | const statically_added_number = staticAdd(1, 2); |
| 48 | fn staticAdd(a: i32, b: i32) i32 { return a + b; } | |
| 49 | ||
| 45 | fn staticAdd(a: i32, b: i32) i32 { | |
| 46 | return a + b; | |
| 47 | } | |
| 50 | 48 | |
| 51 | 49 | test "const expr eval on single expr blocks" { |
| 52 | 50 | assert(constExprEvalOnSingleExprBlocksFn(1, true) == 3); |
| ... | ... | @@ -64,9 +62,6 @@ fn constExprEvalOnSingleExprBlocksFn(x: i32, b: bool) i32 { |
| 64 | 62 | return result; |
| 65 | 63 | } |
| 66 | 64 | |
| 67 | ||
| 68 | ||
| 69 | ||
| 70 | 65 | test "statically initialized list" { |
| 71 | 66 | assert(static_point_list[0].x == 1); |
| 72 | 67 | assert(static_point_list[0].y == 2); |
| ... | ... | @@ -77,7 +72,10 @@ const Point = struct { |
| 77 | 72 | x: i32, |
| 78 | 73 | y: i32, |
| 79 | 74 | }; |
| 80 | const static_point_list = []Point { makePoint(1, 2), makePoint(3, 4) }; | |
| 75 | const static_point_list = []Point { | |
| 76 | makePoint(1, 2), | |
| 77 | makePoint(3, 4), | |
| 78 | }; | |
| 81 | 79 | fn makePoint(x: i32, y: i32) Point { |
| 82 | 80 | return Point { |
| 83 | 81 | .x = x, |
| ... | ... | @@ -85,7 +83,6 @@ fn makePoint(x: i32, y: i32) Point { |
| 85 | 83 | }; |
| 86 | 84 | } |
| 87 | 85 | |
| 88 | ||
| 89 | 86 | test "static eval list init" { |
| 90 | 87 | assert(static_vec3.data[2] == 1.0); |
| 91 | 88 | assert(vec3(0.0, 0.0, 3.0).data[2] == 3.0); |
| ... | ... | @@ -96,17 +93,19 @@ pub const Vec3 = struct { |
| 96 | 93 | }; |
| 97 | 94 | pub fn vec3(x: f32, y: f32, z: f32) Vec3 { |
| 98 | 95 | return Vec3 { |
| 99 | .data = []f32 { x, y, z, }, | |
| 96 | .data = []f32 { | |
| 97 | x, | |
| 98 | y, | |
| 99 | z, | |
| 100 | }, | |
| 100 | 101 | }; |
| 101 | 102 | } |
| 102 | 103 | |
| 103 | ||
| 104 | 104 | test "constant expressions" { |
| 105 | var array : [array_size]u8 = undefined; | |
| 105 | var array: [array_size]u8 = undefined; | |
| 106 | 106 | assert(@sizeOf(@typeOf(array)) == 20); |
| 107 | 107 | } |
| 108 | const array_size : u8 = 20; | |
| 109 | ||
| 108 | const array_size: u8 = 20; | |
| 110 | 109 | |
| 111 | 110 | test "constant struct with negation" { |
| 112 | 111 | assert(vertices[0].x == -0.6); |
| ... | ... | @@ -119,12 +118,29 @@ const Vertex = struct { |
| 119 | 118 | b: f32, |
| 120 | 119 | }; |
| 121 | 120 | const vertices = []Vertex { |
| 122 | Vertex { .x = -0.6, .y = -0.4, .r = 1.0, .g = 0.0, .b = 0.0 }, | |
| 123 | Vertex { .x = 0.6, .y = -0.4, .r = 0.0, .g = 1.0, .b = 0.0 }, | |
| 124 | Vertex { .x = 0.0, .y = 0.6, .r = 0.0, .g = 0.0, .b = 1.0 }, | |
| 121 | Vertex { | |
| 122 | .x = -0.6, | |
| 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 | }; |
| 126 | 143 | |
| 127 | ||
| 128 | 144 | test "statically initialized struct" { |
| 129 | 145 | st_init_str_foo.x += 1; |
| 130 | 146 | assert(st_init_str_foo.x == 14); |
| ... | ... | @@ -133,15 +149,21 @@ const StInitStrFoo = struct { |
| 133 | 149 | x: i32, |
| 134 | 150 | y: bool, |
| 135 | 151 | }; |
| 136 | var st_init_str_foo = StInitStrFoo { .x = 13, .y = true, }; | |
| 137 | ||
| 152 | var st_init_str_foo = StInitStrFoo { | |
| 153 | .x = 13, | |
| 154 | .y = true, | |
| 155 | }; | |
| 138 | 156 | |
| 139 | 157 | test "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 | 159 | assert(y[3] == 4); |
| 142 | 160 | } |
| 143 | const st_init_arr_lit_x = []u8{1,2,3,4}; | |
| 144 | ||
| 161 | const st_init_arr_lit_x = []u8 { | |
| 162 | 1, | |
| 163 | 2, | |
| 164 | 3, | |
| 165 | 4, | |
| 166 | }; | |
| 145 | 167 | |
| 146 | 168 | test "const slice" { |
| 147 | 169 | comptime { |
| ... | ... | @@ -198,14 +220,29 @@ const CmdFn = struct { |
| 198 | 220 | func: fn(i32) i32, |
| 199 | 221 | }; |
| 200 | 222 | |
| 201 | const cmd_fns = []CmdFn{ | |
| 202 | CmdFn {.name = "one", .func = one}, | |
| 203 | CmdFn {.name = "two", .func = two}, | |
| 204 | CmdFn {.name = "three", .func = three}, | |
| 223 | const cmd_fns = []CmdFn { | |
| 224 | CmdFn { | |
| 225 | .name = "one", | |
| 226 | .func = one, | |
| 227 | }, | |
| 228 | CmdFn { | |
| 229 | .name = "two", | |
| 230 | .func = two, | |
| 231 | }, | |
| 232 | CmdFn { | |
| 233 | .name = "three", | |
| 234 | .func = three, | |
| 235 | }, | |
| 205 | 236 | }; |
| 206 | fn one(value: i32) i32 { return value + 1; } | |
| 207 | fn two(value: i32) i32 { return value + 2; } | |
| 208 | fn three(value: i32) i32 { return value + 3; } | |
| 237 | fn one(value: i32) i32 { | |
| 238 | return value + 1; | |
| 239 | } | |
| 240 | fn two(value: i32) i32 { | |
| 241 | return value + 2; | |
| 242 | } | |
| 243 | fn three(value: i32) i32 { | |
| 244 | return value + 3; | |
| 245 | } | |
| 209 | 246 | |
| 210 | 247 | fn performFn(comptime prefix_char: u8, start_value: i32) i32 { |
| 211 | 248 | var result: i32 = start_value; |
| ... | ... | @@ -229,7 +266,7 @@ test "eval @setRuntimeSafety at compile-time" { |
| 229 | 266 | assert(result == 1234); |
| 230 | 267 | } |
| 231 | 268 | |
| 232 | fn fnWithSetRuntimeSafety() i32{ | |
| 269 | fn fnWithSetRuntimeSafety() i32 { | |
| 233 | 270 | @setRuntimeSafety(true); |
| 234 | 271 | return 1234; |
| 235 | 272 | } |
| ... | ... | @@ -244,7 +281,6 @@ fn fnWithFloatMode() f32 { |
| 244 | 281 | return 1234.0; |
| 245 | 282 | } |
| 246 | 283 | |
| 247 | ||
| 248 | 284 | const SimpleStruct = struct { |
| 249 | 285 | field: i32, |
| 250 | 286 | |
| ... | ... | @@ -253,7 +289,9 @@ const SimpleStruct = struct { |
| 253 | 289 | } |
| 254 | 290 | }; |
| 255 | 291 | |
| 256 | var simple_struct = SimpleStruct{ .field = 1234, }; | |
| 292 | var simple_struct = SimpleStruct { | |
| 293 | .field = 1234, | |
| 294 | }; | |
| 257 | 295 | |
| 258 | 296 | const bound_fn = simple_struct.method; |
| 259 | 297 | |
| ... | ... | @@ -261,8 +299,6 @@ test "call method on bound fn referring to var instance" { |
| 261 | 299 | assert(bound_fn() == 1237); |
| 262 | 300 | } |
| 263 | 301 | |
| 264 | ||
| 265 | ||
| 266 | 302 | test "ptr to local array argument at comptime" { |
| 267 | 303 | comptime { |
| 268 | 304 | var bytes: [10]u8 = undefined; |
| ... | ... | @@ -277,7 +313,6 @@ fn modifySomeBytes(bytes: []u8) void { |
| 277 | 313 | bytes[9] = 'b'; |
| 278 | 314 | } |
| 279 | 315 | |
| 280 | ||
| 281 | 316 | test "comparisons 0 <= uint and 0 > uint should be comptime" { |
| 282 | 317 | testCompTimeUIntComparisons(1234); |
| 283 | 318 | } |
| ... | ... | @@ -296,8 +331,6 @@ fn testCompTimeUIntComparisons(x: u32) void { |
| 296 | 331 | } |
| 297 | 332 | } |
| 298 | 333 | |
| 299 | ||
| 300 | ||
| 301 | 334 | test "const ptr to variable data changes at runtime" { |
| 302 | 335 | assert(foo_ref.name[0] == 'a'); |
| 303 | 336 | foo_ref.name = "b"; |
| ... | ... | @@ -308,11 +341,11 @@ const Foo = struct { |
| 308 | 341 | name: []const u8, |
| 309 | 342 | }; |
| 310 | 343 | |
| 311 | var foo_contents = Foo { .name = "a", }; | |
| 344 | var foo_contents = Foo { | |
| 345 | .name = "a", | |
| 346 | }; | |
| 312 | 347 | const foo_ref = &foo_contents; |
| 313 | 348 | |
| 314 | ||
| 315 | ||
| 316 | 349 | test "create global array with for loop" { |
| 317 | 350 | assert(global_array[5] == 5 * 5); |
| 318 | 351 | assert(global_array[9] == 9 * 9); |
| ... | ... | @@ -321,7 +354,7 @@ test "create global array with for loop" { |
| 321 | 354 | const global_array = x: { |
| 322 | 355 | var result: [10]usize = undefined; |
| 323 | 356 | for (result) |*item, index| { |
| 324 | *item = index * index; | |
| 357 | item.* = index * index; | |
| 325 | 358 | } |
| 326 | 359 | break :x result; |
| 327 | 360 | }; |
| ... | ... | @@ -379,7 +412,7 @@ test "f128 at compile time is lossy" { |
| 379 | 412 | |
| 380 | 413 | pub fn TypeWithCompTimeSlice(comptime field_name: []const u8) type { |
| 381 | 414 | return struct { |
| 382 | pub const Node = struct { }; | |
| 415 | pub const Node = struct {}; | |
| 383 | 416 | }; |
| 384 | 417 | } |
| 385 | 418 | |
| ... | ... | @@ -401,10 +434,10 @@ fn copyWithPartialInline(s: []u32, b: []u8) void { |
| 401 | 434 | comptime var i: usize = 0; |
| 402 | 435 | inline while (i < 4) : (i += 1) { |
| 403 | 436 | s[i] = 0; |
| 404 | s[i] |= u32(b[i*4+0]) << 24; | |
| 405 | s[i] |= u32(b[i*4+1]) << 16; | |
| 406 | s[i] |= u32(b[i*4+2]) << 8; | |
| 407 | s[i] |= u32(b[i*4+3]) << 0; | |
| 437 | s[i] |= u32(b[i * 4 + 0]) << 24; | |
| 438 | s[i] |= u32(b[i * 4 + 1]) << 16; | |
| 439 | s[i] |= u32(b[i * 4 + 2]) << 8; | |
| 440 | s[i] |= u32(b[i * 4 + 3]) << 0; | |
| 408 | 441 | } |
| 409 | 442 | } |
| 410 | 443 | |
| ... | ... | @@ -413,7 +446,7 @@ test "binary math operator in partially inlined function" { |
| 413 | 446 | var b: [16]u8 = undefined; |
| 414 | 447 | |
| 415 | 448 | for (b) |*r, i| |
| 416 | *r = u8(i + 1); | |
| 449 | r.* = u8(i + 1); | |
| 417 | 450 | |
| 418 | 451 | copyWithPartialInline(s[0..], b[0..]); |
| 419 | 452 | assert(s[0] == 0x1020304); |
| ... | ... | @@ -422,7 +455,6 @@ test "binary math operator in partially inlined function" { |
| 422 | 455 | assert(s[3] == 0xd0e0f10); |
| 423 | 456 | } |
| 424 | 457 | |
| 425 | ||
| 426 | 458 | test "comptime function with the same args is memoized" { |
| 427 | 459 | comptime { |
| 428 | 460 | assert(MakeType(i32) == MakeType(i32)); |
| ... | ... | @@ -447,12 +479,12 @@ test "comptime function with mutable pointer is not memoized" { |
| 447 | 479 | } |
| 448 | 480 | |
| 449 | 481 | fn increment(value: &i32) void { |
| 450 | *value += 1; | |
| 482 | value.* += 1; | |
| 451 | 483 | } |
| 452 | 484 | |
| 453 | 485 | fn generateTable(comptime T: type) [1010]T { |
| 454 | var res : [1010]T = undefined; | |
| 455 | var i : usize = 0; | |
| 486 | var res: [1010]T = undefined; | |
| 487 | var i: usize = 0; | |
| 456 | 488 | while (i < 1010) : (i += 1) { |
| 457 | 489 | res[i] = T(i); |
| 458 | 490 | } |
| ... | ... | @@ -496,9 +528,10 @@ const SingleFieldStruct = struct { |
| 496 | 528 | } |
| 497 | 529 | }; |
| 498 | 530 | test "const ptr to comptime mutable data is not memoized" { |
| 499 | ||
| 500 | 531 | comptime { |
| 501 | var foo = SingleFieldStruct {.x = 1}; | |
| 532 | var foo = SingleFieldStruct { | |
| 533 | .x = 1, | |
| 534 | }; | |
| 502 | 535 | assert(foo.read_x() == 1); |
| 503 | 536 | foo.x = 2; |
| 504 | 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 | return a + b; |
| 8 | 8 | } |
| 9 | 9 | |
| 10 | ||
| 11 | 10 | test "local variables" { |
| 12 | 11 | testLocVars(2); |
| 13 | 12 | } |
| ... | ... | @@ -16,7 +15,6 @@ fn testLocVars(b: i32) void { |
| 16 | 15 | if (a + b != 3) unreachable; |
| 17 | 16 | } |
| 18 | 17 | |
| 19 | ||
| 20 | 18 | test "void parameters" { |
| 21 | 19 | voidFun(1, void{}, 2, {}); |
| 22 | 20 | } |
| ... | ... | @@ -27,9 +25,8 @@ fn voidFun(a: i32, b: void, c: i32, d: void) void { |
| 27 | 25 | return vv; |
| 28 | 26 | } |
| 29 | 27 | |
| 30 | ||
| 31 | 28 | test "mutable local variables" { |
| 32 | var zero : i32 = 0; | |
| 29 | var zero: i32 = 0; | |
| 33 | 30 | assert(zero == 0); |
| 34 | 31 | |
| 35 | 32 | var i = i32(0); |
| ... | ... | @@ -41,7 +38,7 @@ test "mutable local variables" { |
| 41 | 38 | |
| 42 | 39 | test "separate block scopes" { |
| 43 | 40 | { |
| 44 | const no_conflict : i32 = 5; | |
| 41 | const no_conflict: i32 = 5; | |
| 45 | 42 | assert(no_conflict == 5); |
| 46 | 43 | } |
| 47 | 44 | |
| ... | ... | @@ -56,8 +53,7 @@ test "call function with empty string" { |
| 56 | 53 | acceptsString(""); |
| 57 | 54 | } |
| 58 | 55 | |
| 59 | fn acceptsString(foo: []u8) void { } | |
| 60 | ||
| 56 | fn acceptsString(foo: []u8) void {} | |
| 61 | 57 | |
| 62 | 58 | fn @"weird function name"() i32 { |
| 63 | 59 | return 1234; |
| ... | ... | @@ -70,31 +66,43 @@ test "implicit cast function unreachable return" { |
| 70 | 66 | wantsFnWithVoid(fnWithUnreachable); |
| 71 | 67 | } |
| 72 | 68 | |
| 73 | fn wantsFnWithVoid(f: fn() void) void { } | |
| 69 | fn wantsFnWithVoid(f: fn() void) void {} | |
| 74 | 70 | |
| 75 | 71 | fn fnWithUnreachable() noreturn { |
| 76 | 72 | unreachable; |
| 77 | 73 | } |
| 78 | 74 | |
| 79 | ||
| 80 | 75 | test "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 | 82 | for (fns) |f, i| { |
| 83 | 83 | assert(f() == u32(i) + 5); |
| 84 | 84 | } |
| 85 | 85 | } |
| 86 | fn fn1() u32 {return 5;} | |
| 87 | fn fn2() u32 {return 6;} | |
| 88 | fn fn3() u32 {return 7;} | |
| 89 | fn fn4() u32 {return 8;} | |
| 90 | ||
| 86 | fn fn1() u32 { | |
| 87 | return 5; | |
| 88 | } | |
| 89 | fn fn2() u32 { | |
| 90 | return 6; | |
| 91 | } | |
| 92 | fn fn3() u32 { | |
| 93 | return 7; | |
| 94 | } | |
| 95 | fn fn4() u32 { | |
| 96 | return 8; | |
| 97 | } | |
| 91 | 98 | |
| 92 | 99 | test "inline function call" { |
| 93 | 100 | assert(@inlineCall(add, 3, 9) == 12); |
| 94 | 101 | } |
| 95 | 102 | |
| 96 | fn add(a: i32, b: i32) i32 { return a + b; } | |
| 97 | ||
| 103 | fn add(a: i32, b: i32) i32 { | |
| 104 | return a + b; | |
| 105 | } | |
| 98 | 106 | |
| 99 | 107 | test "number literal as an argument" { |
| 100 | 108 | numberLiteralArg(3); |
| ... | ... | @@ -110,4 +118,4 @@ test "assign inline fn to const variable" { |
| 110 | 118 | a(); |
| 111 | 119 | } |
| 112 | 120 | |
| 113 | inline fn inlineFn() void { } | |
| 121 | inline fn inlineFn() void {} |
test/cases/for.zig+37-7| ... | ... | @@ -3,8 +3,14 @@ const assert = std.debug.assert; |
| 3 | 3 | const mem = std.mem; |
| 4 | 4 | |
| 5 | 5 | test "continue in for loop" { |
| 6 | const array = []i32 {1, 2, 3, 4, 5}; | |
| 7 | var sum : i32 = 0; | |
| 6 | const array = []i32 { | |
| 7 | 1, | |
| 8 | 2, | |
| 9 | 3, | |
| 10 | 4, | |
| 11 | 5, | |
| 12 | }; | |
| 13 | var sum: i32 = 0; | |
| 8 | 14 | for (array) |x| { |
| 9 | 15 | sum += x; |
| 10 | 16 | if (x < 3) { |
| ... | ... | @@ -24,17 +30,39 @@ test "for loop with pointer elem var" { |
| 24 | 30 | } |
| 25 | 31 | fn mangleString(s: []u8) void { |
| 26 | 32 | for (s) |*c| { |
| 27 | *c += 1; | |
| 33 | c.* += 1; | |
| 28 | 34 | } |
| 29 | 35 | } |
| 30 | 36 | |
| 31 | 37 | test "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 | }; | |
| 33 | 56 | |
| 34 | 57 | var buffer: [expected_result.len]u8 = undefined; |
| 35 | 58 | var buf_index: usize = 0; |
| 36 | 59 | |
| 37 | const array = []u8 {9, 8, 7, 6}; | |
| 60 | const array = []u8 { | |
| 61 | 9, | |
| 62 | 8, | |
| 63 | 7, | |
| 64 | 6, | |
| 65 | }; | |
| 38 | 66 | for (array) |item| { |
| 39 | 67 | buffer[buf_index] = item; |
| 40 | 68 | buf_index += 1; |
| ... | ... | @@ -65,7 +93,8 @@ fn testBreakOuter() void { |
| 65 | 93 | var array = "aoeu"; |
| 66 | 94 | var count: usize = 0; |
| 67 | 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 | 98 | count += 1; |
| 70 | 99 | break :outer; |
| 71 | 100 | } |
| ... | ... | @@ -82,7 +111,8 @@ fn testContinueOuter() void { |
| 82 | 111 | var array = "aoeu"; |
| 83 | 112 | var counter: usize = 0; |
| 84 | 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 | 116 | counter += 1; |
| 87 | 117 | continue :outer; |
| 88 | 118 | } |
test/cases/generics.zig+28-14| ... | ... | @@ -37,7 +37,6 @@ test "fn with comptime args" { |
| 37 | 37 | assert(sameButWithFloats(0.43, 0.49) == 0.49); |
| 38 | 38 | } |
| 39 | 39 | |
| 40 | ||
| 41 | 40 | test "var params" { |
| 42 | 41 | assert(max_i32(12, 34) == 34); |
| 43 | 42 | assert(max_f64(1.2, 3.4) == 3.4); |
| ... | ... | @@ -60,7 +59,6 @@ fn max_f64(a: f64, b: f64) f64 { |
| 60 | 59 | return max_var(a, b); |
| 61 | 60 | } |
| 62 | 61 | |
| 63 | ||
| 64 | 62 | pub fn List(comptime T: type) type { |
| 65 | 63 | return SmallList(T, 8); |
| 66 | 64 | } |
| ... | ... | @@ -82,10 +80,15 @@ test "function with return type type" { |
| 82 | 80 | assert(list2.prealloc_items.len == 8); |
| 83 | 81 | } |
| 84 | 82 | |
| 85 | ||
| 86 | 83 | test "generic struct" { |
| 87 | var a1 = GenNode(i32) {.value = 13, .next = null,}; | |
| 88 | var b1 = GenNode(bool) {.value = true, .next = null,}; | |
| 84 | var a1 = GenNode(i32) { | |
| 85 | .value = 13, | |
| 86 | .next = null, | |
| 87 | }; | |
| 88 | var b1 = GenNode(bool) { | |
| 89 | .value = true, | |
| 90 | .next = null, | |
| 91 | }; | |
| 89 | 92 | assert(a1.value == 13); |
| 90 | 93 | assert(a1.value == a1.getVal()); |
| 91 | 94 | assert(b1.getVal()); |
| ... | ... | @@ -94,7 +97,9 @@ fn GenNode(comptime T: type) type { |
| 94 | 97 | return struct { |
| 95 | 98 | value: T, |
| 96 | 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 | } |
| 100 | 105 | |
| ... | ... | @@ -107,7 +112,6 @@ fn GenericDataThing(comptime count: isize) type { |
| 107 | 112 | }; |
| 108 | 113 | } |
| 109 | 114 | |
| 110 | ||
| 111 | 115 | test "use generic param in generic param" { |
| 112 | 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 | 119 | return a + b; |
| 116 | 120 | } |
| 117 | 121 | |
| 118 | ||
| 119 | 122 | test "generic fn with implicit cast" { |
| 120 | 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 | } | |
| 129 | fn getByte(ptr: ?&const u8) u8 { | |
| 130 | return ??ptr.*; | |
| 122 | 131 | } |
| 123 | fn getByte(ptr: ?&const u8) u8 {return *??ptr;} | |
| 124 | 132 | fn getFirstByte(comptime T: type, mem: []const T) u8 { |
| 125 | 133 | return getByte(@ptrCast(&const u8, &mem[0])); |
| 126 | 134 | } |
| 127 | 135 | |
| 136 | const foos = []fn(var) bool { | |
| 137 | foo1, | |
| 138 | foo2, | |
| 139 | }; | |
| 128 | 140 | |
| 129 | const foos = []fn(var) bool { foo1, foo2 }; | |
| 130 | ||
| 131 | fn foo1(arg: var) bool { return arg; } | |
| 132 | fn foo2(arg: var) bool { return !arg; } | |
| 141 | fn foo1(arg: var) bool { | |
| 142 | return arg; | |
| 143 | } | |
| 144 | fn foo2(arg: var) bool { | |
| 145 | return !arg; | |
| 146 | } | |
| 133 | 147 | |
| 134 | 148 | test "array of generic fns" { |
| 135 | 149 | assert(foos[0](true)); |
test/cases/if.zig-1| ... | ... | @@ -23,7 +23,6 @@ fn firstEqlThird(a: i32, b: i32, c: i32) void { |
| 23 | 23 | } |
| 24 | 24 | } |
| 25 | 25 | |
| 26 | ||
| 27 | 26 | test "else if expression" { |
| 28 | 27 | assert(elseIfExpressionF(1) == 1); |
| 29 | 28 | } |
test/cases/import/a_namespace.zig+3-1| ... | ... | @@ -1 +1,3 @@ |
| 1 | pub fn foo() i32 { return 1234; } | |
| 1 | pub 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 | 11 | }; |
| 12 | 12 | } |
| 13 | 13 | |
| 14 | fn getErrInt() error!i32 { return 0; } | |
| 14 | fn getErrInt() error!i32 { | |
| 15 | return 0; | |
| 16 | } | |
| 15 | 17 | |
| 16 | 18 | test "ir block deps" { |
| 17 | 19 | assert((foo(1) catch unreachable) == 0); |
test/cases/math.zig+40-52| ... | ... | @@ -28,25 +28,12 @@ fn testDivision() void { |
| 28 | 28 | assert(divTrunc(f32, -5.0, 3.0) == -1.0); |
| 29 | 29 | |
| 30 | 30 | comptime { |
| 31 | assert( | |
| 32 | 1194735857077236777412821811143690633098347576 % | |
| 33 | 508740759824825164163191790951174292733114988 == | |
| 34 | 177254337427586449086438229241342047632117600); | |
| 35 | assert(@rem(-1194735857077236777412821811143690633098347576, | |
| 36 | 508740759824825164163191790951174292733114988) == | |
| 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); | |
| 31 | assert(1194735857077236777412821811143690633098347576 % 508740759824825164163191790951174292733114988 == 177254337427586449086438229241342047632117600); | |
| 32 | assert(@rem(-1194735857077236777412821811143690633098347576, 508740759824825164163191790951174292733114988) == -177254337427586449086438229241342047632117600); | |
| 33 | assert(1194735857077236777412821811143690633098347576 / 508740759824825164163191790951174292733114988 == 2); | |
| 34 | assert(@divTrunc(-1194735857077236777412821811143690633098347576, 508740759824825164163191790951174292733114988) == -2); | |
| 35 | assert(@divTrunc(1194735857077236777412821811143690633098347576, -508740759824825164163191790951174292733114988) == -2); | |
| 36 | assert(@divTrunc(-1194735857077236777412821811143690633098347576, -508740759824825164163191790951174292733114988) == 2); | |
| 50 | 37 | assert(4126227191251978491697987544882340798050766755606969681711 % 10 == 1); |
| 51 | 38 | } |
| 52 | 39 | } |
| ... | ... | @@ -114,18 +101,28 @@ fn ctz(x: var) usize { |
| 114 | 101 | |
| 115 | 102 | test "assignment operators" { |
| 116 | 103 | var i: u32 = 0; |
| 117 | i += 5; assert(i == 5); | |
| 118 | i -= 2; assert(i == 3); | |
| 119 | i *= 20; assert(i == 60); | |
| 120 | i /= 3; assert(i == 20); | |
| 121 | i %= 11; assert(i == 9); | |
| 122 | i <<= 1; assert(i == 18); | |
| 123 | i >>= 2; assert(i == 4); | |
| 104 | i += 5; | |
| 105 | assert(i == 5); | |
| 106 | i -= 2; | |
| 107 | assert(i == 3); | |
| 108 | i *= 20; | |
| 109 | assert(i == 60); | |
| 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 | 118 | i = 6; |
| 125 | i &= 5; assert(i == 4); | |
| 126 | i ^= 6; assert(i == 2); | |
| 119 | i &= 5; | |
| 120 | assert(i == 4); | |
| 121 | i ^= 6; | |
| 122 | assert(i == 2); | |
| 127 | 123 | i = 6; |
| 128 | i |= 3; assert(i == 7); | |
| 124 | i |= 3; | |
| 125 | assert(i == 7); | |
| 129 | 126 | } |
| 130 | 127 | |
| 131 | 128 | test "three expr in a row" { |
| ... | ... | @@ -138,7 +135,7 @@ fn testThreeExprInARow(f: bool, t: bool) void { |
| 138 | 135 | assertFalse(1 | 2 | 4 != 7); |
| 139 | 136 | assertFalse(3 ^ 6 ^ 8 != 13); |
| 140 | 137 | assertFalse(7 & 14 & 28 != 4); |
| 141 | assertFalse(9 << 1 << 2 != 9 << 3); | |
| 138 | assertFalse(9 << 1 << 2 != 9 << 3); | |
| 142 | 139 | assertFalse(90 >> 1 >> 2 != 90 >> 3); |
| 143 | 140 | assertFalse(100 - 1 + 1000 != 1099); |
| 144 | 141 | assertFalse(5 * 4 / 2 % 3 != 1); |
| ... | ... | @@ -150,7 +147,6 @@ fn assertFalse(b: bool) void { |
| 150 | 147 | assert(!b); |
| 151 | 148 | } |
| 152 | 149 | |
| 153 | ||
| 154 | 150 | test "const number literal" { |
| 155 | 151 | const one = 1; |
| 156 | 152 | const eleven = ten + one; |
| ... | ... | @@ -159,8 +155,6 @@ test "const number literal" { |
| 159 | 155 | } |
| 160 | 156 | const ten = 10; |
| 161 | 157 | |
| 162 | ||
| 163 | ||
| 164 | 158 | test "unsigned wrapping" { |
| 165 | 159 | testUnsignedWrappingEval(@maxValue(u32)); |
| 166 | 160 | comptime testUnsignedWrappingEval(@maxValue(u32)); |
| ... | ... | @@ -214,8 +208,12 @@ const DivResult = struct { |
| 214 | 208 | }; |
| 215 | 209 | |
| 216 | 210 | test "binary not" { |
| 217 | assert(comptime x: {break :x ~u16(0b1010101010101010) == 0b0101010101010101;}); | |
| 218 | assert(comptime x: {break :x ~u64(2147483647) == 18446744071562067968;}); | |
| 211 | assert(comptime x: { | |
| 212 | break :x ~u16(0b1010101010101010) == 0b0101010101010101; | |
| 213 | }); | |
| 214 | assert(comptime x: { | |
| 215 | break :x ~u64(2147483647) == 18446744071562067968; | |
| 216 | }); | |
| 219 | 217 | testBinaryNot(0b1010101010101010); |
| 220 | 218 | } |
| 221 | 219 | |
| ... | ... | @@ -319,27 +317,15 @@ fn testShrExact(x: u8) void { |
| 319 | 317 | |
| 320 | 318 | test "big number addition" { |
| 321 | 319 | comptime { |
| 322 | assert( | |
| 323 | 35361831660712422535336160538497375248 + | |
| 324 | 101752735581729509668353361206450473702 == | |
| 325 | 137114567242441932203689521744947848950); | |
| 326 | assert( | |
| 327 | 594491908217841670578297176641415611445982232488944558774612 + | |
| 328 | 390603545391089362063884922208143568023166603618446395589768 == | |
| 329 | 985095453608931032642182098849559179469148836107390954364380); | |
| 320 | assert(35361831660712422535336160538497375248 + 101752735581729509668353361206450473702 == 137114567242441932203689521744947848950); | |
| 321 | assert(594491908217841670578297176641415611445982232488944558774612 + 390603545391089362063884922208143568023166603618446395589768 == 985095453608931032642182098849559179469148836107390954364380); | |
| 330 | 322 | } |
| 331 | 323 | } |
| 332 | 324 | |
| 333 | 325 | test "big number multiplication" { |
| 334 | 326 | comptime { |
| 335 | assert( | |
| 336 | 45960427431263824329884196484953148229 * | |
| 337 | 128339149605334697009938835852565949723 == | |
| 338 | 5898522172026096622534201617172456926982464453350084962781392314016180490567); | |
| 339 | assert( | |
| 340 | 594491908217841670578297176641415611445982232488944558774612 * | |
| 341 | 390603545391089362063884922208143568023166603618446395589768 == | |
| 342 | 232210647056203049913662402532976186578842425262306016094292237500303028346593132411865381225871291702600263463125370016); | |
| 327 | assert(45960427431263824329884196484953148229 * 128339149605334697009938835852565949723 == 5898522172026096622534201617172456926982464453350084962781392314016180490567); | |
| 328 | assert(594491908217841670578297176641415611445982232488944558774612 * 390603545391089362063884922208143568023166603618446395589768 == 232210647056203049913662402532976186578842425262306016094292237500303028346593132411865381225871291702600263463125370016); | |
| 343 | 329 | } |
| 344 | 330 | } |
| 345 | 331 | |
| ... | ... | @@ -380,7 +366,9 @@ test "f128" { |
| 380 | 366 | comptime test_f128(); |
| 381 | 367 | } |
| 382 | 368 | |
| 383 | fn make_f128(x: f128) f128 { return x; } | |
| 369 | fn make_f128(x: f128) f128 { | |
| 370 | return x; | |
| 371 | } | |
| 384 | 372 | |
| 385 | 373 | fn test_f128() void { |
| 386 | 374 | assert(@sizeOf(f128) == 16); |
test/cases/misc.zig+138-87| ... | ... | @@ -4,6 +4,7 @@ const cstr = @import("std").cstr; |
| 4 | 4 | const builtin = @import("builtin"); |
| 5 | 5 | |
| 6 | 6 | // normal comment |
| 7 | ||
| 7 | 8 | /// this is a documentation comment |
| 8 | 9 | /// doc comment line 2 |
| 9 | 10 | fn emptyFunctionWithComments() void {} |
| ... | ... | @@ -16,8 +17,7 @@ comptime { |
| 16 | 17 | @export("disabledExternFn", disabledExternFn, builtin.GlobalLinkage.Internal); |
| 17 | 18 | } |
| 18 | 19 | |
| 19 | extern fn disabledExternFn() void { | |
| 20 | } | |
| 20 | extern fn disabledExternFn() void {} | |
| 21 | 21 | |
| 22 | 22 | test "call disabled extern fn" { |
| 23 | 23 | disabledExternFn(); |
| ... | ... | @@ -110,17 +110,29 @@ fn testShortCircuit(f: bool, t: bool) void { |
| 110 | 110 | var hit_3 = f; |
| 111 | 111 | var hit_4 = f; |
| 112 | 112 | |
| 113 | if (t or x: {assert(f); break :x f;}) { | |
| 113 | if (t or x: { | |
| 114 | assert(f); | |
| 115 | break :x f; | |
| 116 | }) { | |
| 114 | 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 | 123 | assert(f); |
| 118 | 124 | } |
| 119 | 125 | |
| 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 | 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 | 136 | assert(f); |
| 125 | 137 | } else { |
| 126 | 138 | hit_4 = t; |
| ... | ... | @@ -146,8 +158,8 @@ test "return string from function" { |
| 146 | 158 | assert(mem.eql(u8, first4KeysOfHomeRow(), "aoeu")); |
| 147 | 159 | } |
| 148 | 160 | |
| 149 | const g1 : i32 = 1233 + 1; | |
| 150 | var g2 : i32 = 0; | |
| 161 | const g1: i32 = 1233 + 1; | |
| 162 | var g2: i32 = 0; | |
| 151 | 163 | |
| 152 | 164 | test "global variables" { |
| 153 | 165 | assert(g2 == 0); |
| ... | ... | @@ -155,10 +167,9 @@ test "global variables" { |
| 155 | 167 | assert(g2 == 1234); |
| 156 | 168 | } |
| 157 | 169 | |
| 158 | ||
| 159 | 170 | test "memcpy and memset intrinsics" { |
| 160 | var foo : [20]u8 = undefined; | |
| 161 | var bar : [20]u8 = undefined; | |
| 171 | var foo: [20]u8 = undefined; | |
| 172 | var bar: [20]u8 = undefined; | |
| 162 | 173 | |
| 163 | 174 | @memset(&foo[0], 'A', foo.len); |
| 164 | 175 | @memcpy(&bar[0], &foo[0], bar.len); |
| ... | ... | @@ -167,12 +178,14 @@ test "memcpy and memset intrinsics" { |
| 167 | 178 | } |
| 168 | 179 | |
| 169 | 180 | test "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 | 184 | assert(x == comptime 6); |
| 172 | 185 | } |
| 173 | 186 | |
| 174 | 187 | test "slicing" { |
| 175 | var array : [20]i32 = undefined; | |
| 188 | var array: [20]i32 = undefined; | |
| 176 | 189 | |
| 177 | 190 | array[5] = 1234; |
| 178 | 191 | |
| ... | ... | @@ -187,15 +200,15 @@ test "slicing" { |
| 187 | 200 | if (slice_rest.len != 10) unreachable; |
| 188 | 201 | } |
| 189 | 202 | |
| 190 | ||
| 191 | 203 | test "constant equal function pointers" { |
| 192 | 204 | const alias = emptyFn; |
| 193 | assert(comptime x: {break :x emptyFn == alias;}); | |
| 205 | assert(comptime x: { | |
| 206 | break :x emptyFn == alias; | |
| 207 | }); | |
| 194 | 208 | } |
| 195 | 209 | |
| 196 | 210 | fn emptyFn() void {} |
| 197 | 211 | |
| 198 | ||
| 199 | 212 | test "hex escape" { |
| 200 | 213 | assert(mem.eql(u8, "\x68\x65\x6c\x6c\x6f", "hello")); |
| 201 | 214 | } |
| ... | ... | @@ -219,7 +232,7 @@ test "string escapes" { |
| 219 | 232 | } |
| 220 | 233 | |
| 221 | 234 | test "multiline string" { |
| 222 | const s1 = | |
| 235 | const s1 = | |
| 223 | 236 | \\one |
| 224 | 237 | \\two) |
| 225 | 238 | \\three |
| ... | ... | @@ -229,7 +242,7 @@ test "multiline string" { |
| 229 | 242 | } |
| 230 | 243 | |
| 231 | 244 | test "multiline C string" { |
| 232 | const s1 = | |
| 245 | const s1 = | |
| 233 | 246 | c\\one |
| 234 | 247 | c\\two) |
| 235 | 248 | c\\three |
| ... | ... | @@ -238,18 +251,16 @@ test "multiline C string" { |
| 238 | 251 | assert(cstr.cmp(s1, s2) == 0); |
| 239 | 252 | } |
| 240 | 253 | |
| 241 | ||
| 242 | 254 | test "type equality" { |
| 243 | 255 | assert(&const u8 != &u8); |
| 244 | 256 | } |
| 245 | 257 | |
| 246 | ||
| 247 | 258 | const global_a: i32 = 1234; |
| 248 | 259 | const global_b: &const i32 = &global_a; |
| 249 | 260 | const global_c: &const f32 = @ptrCast(&const f32, global_b); |
| 250 | 261 | test "compile time global reinterpret" { |
| 251 | 262 | const d = @ptrCast(&const i32, global_c); |
| 252 | assert(*d == 1234); | |
| 263 | assert(d.* == 1234); | |
| 253 | 264 | } |
| 254 | 265 | |
| 255 | 266 | test "explicit cast maybe pointers" { |
| ... | ... | @@ -261,12 +272,11 @@ test "generic malloc free" { |
| 261 | 272 | const a = memAlloc(u8, 10) catch unreachable; |
| 262 | 273 | memFree(u8, a); |
| 263 | 274 | } |
| 264 | var some_mem : [100]u8 = undefined; | |
| 275 | var some_mem: [100]u8 = undefined; | |
| 265 | 276 | fn memAlloc(comptime T: type, n: usize) error![]T { |
| 266 | 277 | return @ptrCast(&T, &some_mem[0])[0..n]; |
| 267 | 278 | } |
| 268 | fn memFree(comptime T: type, memory: []T) void { } | |
| 269 | ||
| 279 | fn memFree(comptime T: type, memory: []T) void {} | |
| 270 | 280 | |
| 271 | 281 | test "cast undefined" { |
| 272 | 282 | const array: [100]u8 = undefined; |
| ... | ... | @@ -275,32 +285,35 @@ test "cast undefined" { |
| 275 | 285 | } |
| 276 | 286 | fn testCastUndefined(x: []const u8) void {} |
| 277 | 287 | |
| 278 | ||
| 279 | 288 | test "cast small unsigned to larger signed" { |
| 280 | 289 | assert(castSmallUnsignedToLargerSigned1(200) == i16(200)); |
| 281 | 290 | assert(castSmallUnsignedToLargerSigned2(9999) == i64(9999)); |
| 282 | 291 | } |
| 283 | fn castSmallUnsignedToLargerSigned1(x: u8) i16 { return x; } | |
| 284 | fn castSmallUnsignedToLargerSigned2(x: u16) i64 { return x; } | |
| 285 | ||
| 292 | fn castSmallUnsignedToLargerSigned1(x: u8) i16 { | |
| 293 | return x; | |
| 294 | } | |
| 295 | fn castSmallUnsignedToLargerSigned2(x: u16) i64 { | |
| 296 | return x; | |
| 297 | } | |
| 286 | 298 | |
| 287 | 299 | test "implicit cast after unreachable" { |
| 288 | 300 | assert(outer() == 1234); |
| 289 | 301 | } |
| 290 | fn inner() i32 { return 1234; } | |
| 302 | fn inner() i32 { | |
| 303 | return 1234; | |
| 304 | } | |
| 291 | 305 | fn outer() i64 { |
| 292 | 306 | return inner(); |
| 293 | 307 | } |
| 294 | 308 | |
| 295 | ||
| 296 | 309 | test "pointer dereferencing" { |
| 297 | 310 | var x = i32(3); |
| 298 | 311 | const y = &x; |
| 299 | 312 | |
| 300 | *y += 1; | |
| 313 | y.* += 1; | |
| 301 | 314 | |
| 302 | 315 | assert(x == 4); |
| 303 | assert(*y == 4); | |
| 316 | assert(y.* == 4); | |
| 304 | 317 | } |
| 305 | 318 | |
| 306 | 319 | test "call result of if else expression" { |
| ... | ... | @@ -310,9 +323,12 @@ test "call result of if else expression" { |
| 310 | 323 | fn f2(x: bool) []const u8 { |
| 311 | 324 | return (if (x) fA else fB)(); |
| 312 | 325 | } |
| 313 | fn fA() []const u8 { return "a"; } | |
| 314 | fn fB() []const u8 { return "b"; } | |
| 315 | ||
| 326 | fn fA() []const u8 { | |
| 327 | return "a"; | |
| 328 | } | |
| 329 | fn fB() []const u8 { | |
| 330 | return "b"; | |
| 331 | } | |
| 316 | 332 | |
| 317 | 333 | test "const expression eval handling of variables" { |
| 318 | 334 | var x = true; |
| ... | ... | @@ -321,8 +337,6 @@ test "const expression eval handling of variables" { |
| 321 | 337 | } |
| 322 | 338 | } |
| 323 | 339 | |
| 324 | ||
| 325 | ||
| 326 | 340 | test "constant enum initialization with differing sizes" { |
| 327 | 341 | test3_1(test3_foo); |
| 328 | 342 | test3_2(test3_bar); |
| ... | ... | @@ -336,10 +350,17 @@ const Test3Point = struct { |
| 336 | 350 | x: i32, |
| 337 | 351 | y: i32, |
| 338 | 352 | }; |
| 339 | const test3_foo = Test3Foo { .Three = Test3Point {.x = 3, .y = 4}}; | |
| 340 | const test3_bar = Test3Foo { .Two = 13}; | |
| 353 | const test3_foo = Test3Foo { | |
| 354 | .Three = Test3Point { | |
| 355 | .x = 3, | |
| 356 | .y = 4, | |
| 357 | }, | |
| 358 | }; | |
| 359 | const test3_bar = Test3Foo { | |
| 360 | .Two = 13, | |
| 361 | }; | |
| 341 | 362 | fn test3_1(f: &const Test3Foo) void { |
| 342 | switch (*f) { | |
| 363 | switch (f.*) { | |
| 343 | 364 | Test3Foo.Three => |pt| { |
| 344 | 365 | assert(pt.x == 3); |
| 345 | 366 | assert(pt.y == 4); |
| ... | ... | @@ -348,7 +369,7 @@ fn test3_1(f: &const Test3Foo) void { |
| 348 | 369 | } |
| 349 | 370 | } |
| 350 | 371 | fn test3_2(f: &const Test3Foo) void { |
| 351 | switch (*f) { | |
| 372 | switch (f.*) { | |
| 352 | 373 | Test3Foo.Two => |x| { |
| 353 | 374 | assert(x == 13); |
| 354 | 375 | }, |
| ... | ... | @@ -356,23 +377,19 @@ fn test3_2(f: &const Test3Foo) void { |
| 356 | 377 | } |
| 357 | 378 | } |
| 358 | 379 | |
| 359 | ||
| 360 | 380 | test "character literals" { |
| 361 | 381 | assert('\'' == single_quote); |
| 362 | 382 | } |
| 363 | 383 | const single_quote = '\''; |
| 364 | 384 | |
| 365 | ||
| 366 | ||
| 367 | 385 | test "take address of parameter" { |
| 368 | 386 | testTakeAddressOfParameter(12.34); |
| 369 | 387 | } |
| 370 | 388 | fn testTakeAddressOfParameter(f: f32) void { |
| 371 | 389 | const f_ptr = &f; |
| 372 | assert(*f_ptr == 12.34); | |
| 390 | assert(f_ptr.* == 12.34); | |
| 373 | 391 | } |
| 374 | 392 | |
| 375 | ||
| 376 | 393 | test "pointer comparison" { |
| 377 | 394 | const a = ([]const u8)("a"); |
| 378 | 395 | const b = &a; |
| ... | ... | @@ -382,23 +399,30 @@ fn ptrEql(a: &const []const u8, b: &const []const u8) bool { |
| 382 | 399 | return a == b; |
| 383 | 400 | } |
| 384 | 401 | |
| 385 | ||
| 386 | 402 | test "C string concatenation" { |
| 387 | 403 | const a = c"OK" ++ c" IT " ++ c"WORKED"; |
| 388 | 404 | const b = c"OK IT WORKED"; |
| 389 | 405 | |
| 390 | 406 | const len = cstr.len(b); |
| 391 | 407 | const len_with_null = len + 1; |
| 392 | {var i: u32 = 0; while (i < len_with_null) : (i += 1) { | |
| 393 | assert(a[i] == b[i]); | |
| 394 | }} | |
| 408 | { | |
| 409 | var i: u32 = 0; | |
| 410 | while (i < len_with_null) : (i += 1) { | |
| 411 | assert(a[i] == b[i]); | |
| 412 | } | |
| 413 | } | |
| 395 | 414 | assert(a[len] == 0); |
| 396 | 415 | assert(b[len] == 0); |
| 397 | 416 | } |
| 398 | 417 | |
| 399 | 418 | test "cast slice to u8 slice" { |
| 400 | 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 | 426 | const big_thing_slice: []i32 = big_thing_array[0..]; |
| 403 | 427 | const bytes = ([]u8)(big_thing_slice); |
| 404 | 428 | assert(bytes.len == 4 * 4); |
| ... | ... | @@ -421,25 +445,22 @@ test "pointer to void return type" { |
| 421 | 445 | } |
| 422 | 446 | fn testPointerToVoidReturnType() error!void { |
| 423 | 447 | const a = testPointerToVoidReturnType2(); |
| 424 | return *a; | |
| 448 | return a.*; | |
| 425 | 449 | } |
| 426 | 450 | const test_pointer_to_void_return_type_x = void{}; |
| 427 | 451 | fn testPointerToVoidReturnType2() &const void { |
| 428 | 452 | return &test_pointer_to_void_return_type_x; |
| 429 | 453 | } |
| 430 | 454 | |
| 431 | ||
| 432 | 455 | test "non const ptr to aliased type" { |
| 433 | 456 | const int = i32; |
| 434 | 457 | assert(?&int == ?&i32); |
| 435 | 458 | } |
| 436 | 459 | |
| 437 | ||
| 438 | ||
| 439 | 460 | test "array 2D const double ptr" { |
| 440 | 461 | const rect_2d_vertexes = [][1]f32 { |
| 441 | []f32{1.0}, | |
| 442 | []f32{2.0}, | |
| 462 | []f32 {1.0}, | |
| 463 | []f32 {2.0}, | |
| 443 | 464 | }; |
| 444 | 465 | testArray2DConstDoublePtr(&rect_2d_vertexes[0][0]); |
| 445 | 466 | } |
| ... | ... | @@ -450,10 +471,21 @@ fn testArray2DConstDoublePtr(ptr: &const f32) void { |
| 450 | 471 | } |
| 451 | 472 | |
| 452 | 473 | const Tid = builtin.TypeId; |
| 453 | const AStruct = struct { x: i32, }; | |
| 454 | const AnEnum = enum { One, Two, }; | |
| 455 | const AUnionEnum = union(enum) { One: i32, Two: void, }; | |
| 456 | const AUnion = union { One: void, Two: void }; | |
| 474 | const AStruct = struct { | |
| 475 | x: i32, | |
| 476 | }; | |
| 477 | const AnEnum = enum { | |
| 478 | One, | |
| 479 | Two, | |
| 480 | }; | |
| 481 | const AUnionEnum = union(enum) { | |
| 482 | One: i32, | |
| 483 | Two: void, | |
| 484 | }; | |
| 485 | const AUnion = union { | |
| 486 | One: void, | |
| 487 | Two: void, | |
| 488 | }; | |
| 457 | 489 | |
| 458 | 490 | test "@typeId" { |
| 459 | 491 | comptime { |
| ... | ... | @@ -481,9 +513,11 @@ test "@typeId" { |
| 481 | 513 | assert(@typeId(@typeOf(AUnionEnum.One)) == Tid.Enum); |
| 482 | 514 | assert(@typeId(AUnionEnum) == Tid.Union); |
| 483 | 515 | assert(@typeId(AUnion) == Tid.Union); |
| 484 | assert(@typeId(fn()void) == Tid.Fn); | |
| 516 | assert(@typeId(fn() void) == Tid.Fn); | |
| 485 | 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 | 521 | // TODO bound fn |
| 488 | 522 | // TODO arg tuple |
| 489 | 523 | // TODO opaque |
| ... | ... | @@ -499,8 +533,7 @@ test "@canImplicitCast" { |
| 499 | 533 | } |
| 500 | 534 | |
| 501 | 535 | test "@typeName" { |
| 502 | const Struct = struct { | |
| 503 | }; | |
| 536 | const Struct = struct {}; | |
| 504 | 537 | const Union = union { |
| 505 | 538 | unused: u8, |
| 506 | 539 | }; |
| ... | ... | @@ -525,14 +558,19 @@ fn TypeFromFn(comptime T: type) type { |
| 525 | 558 | test "volatile load and store" { |
| 526 | 559 | var number: i32 = 1234; |
| 527 | 560 | const ptr = (&volatile i32)(&number); |
| 528 | *ptr += 1; | |
| 529 | assert(*ptr == 1235); | |
| 561 | ptr.* += 1; | |
| 562 | assert(ptr.* == 1235); | |
| 530 | 563 | } |
| 531 | 564 | |
| 532 | 565 | test "slice string literal has type []const u8" { |
| 533 | 566 | comptime { |
| 534 | 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 | 574 | assert(@typeOf(array[0..]) == []const i32); |
| 537 | 575 | } |
| 538 | 576 | } |
| ... | ... | @@ -544,12 +582,15 @@ const GDTEntry = struct { |
| 544 | 582 | field: i32, |
| 545 | 583 | }; |
| 546 | 584 | var gdt = []GDTEntry { |
| 547 | GDTEntry {.field = 1}, | |
| 548 | GDTEntry {.field = 2}, | |
| 585 | GDTEntry { | |
| 586 | .field = 1, | |
| 587 | }, | |
| 588 | GDTEntry { | |
| 589 | .field = 2, | |
| 590 | }, | |
| 549 | 591 | }; |
| 550 | 592 | var global_ptr = &gdt[0]; |
| 551 | 593 | |
| 552 | ||
| 553 | 594 | // can't really run this test but we can make sure it has no compile error |
| 554 | 595 | // and generates code |
| 555 | 596 | const vram = @intToPtr(&volatile u8, 0x20000000)[0..0x8000]; |
| ... | ... | @@ -584,7 +625,7 @@ test "comptime if inside runtime while which unconditionally breaks" { |
| 584 | 625 | } |
| 585 | 626 | fn testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(cond: bool) void { |
| 586 | 627 | while (cond) { |
| 587 | if (false) { } | |
| 628 | if (false) {} | |
| 588 | 629 | break; |
| 589 | 630 | } |
| 590 | 631 | } |
| ... | ... | @@ -607,7 +648,9 @@ fn testStructInFn() void { |
| 607 | 648 | kind: BlockKind, |
| 608 | 649 | }; |
| 609 | 650 | |
| 610 | var block = Block { .kind = 1234 }; | |
| 651 | var block = Block { | |
| 652 | .kind = 1234, | |
| 653 | }; | |
| 611 | 654 | |
| 612 | 655 | block.kind += 1; |
| 613 | 656 | |
| ... | ... | @@ -617,7 +660,9 @@ fn testStructInFn() void { |
| 617 | 660 | fn fnThatClosesOverLocalConst() type { |
| 618 | 661 | const c = 1; |
| 619 | 662 | return struct { |
| 620 | fn g() i32 { return c; } | |
| 663 | fn g() i32 { | |
| 664 | return c; | |
| 665 | } | |
| 621 | 666 | }; |
| 622 | 667 | } |
| 623 | 668 | |
| ... | ... | @@ -635,22 +680,29 @@ fn thisIsAColdFn() void { |
| 635 | 680 | @setCold(true); |
| 636 | 681 | } |
| 637 | 682 | |
| 638 | ||
| 639 | const PackedStruct = packed struct { a: u8, b: u8, }; | |
| 640 | const PackedUnion = packed union { a: u8, b: u32, }; | |
| 641 | const PackedEnum = packed enum { A, B, }; | |
| 683 | const PackedStruct = packed struct { | |
| 684 | a: u8, | |
| 685 | b: u8, | |
| 686 | }; | |
| 687 | const PackedUnion = packed union { | |
| 688 | a: u8, | |
| 689 | b: u32, | |
| 690 | }; | |
| 691 | const PackedEnum = packed enum { | |
| 692 | A, | |
| 693 | B, | |
| 694 | }; | |
| 642 | 695 | |
| 643 | 696 | test "packed struct, enum, union parameters in extern function" { |
| 644 | testPackedStuff( | |
| 645 | PackedStruct{.a = 1, .b = 2}, | |
| 646 | PackedUnion{.a = 1}, | |
| 647 | PackedEnum.A, | |
| 648 | ); | |
| 649 | } | |
| 650 | ||
| 651 | export fn testPackedStuff(a: &const PackedStruct, b: &const PackedUnion, c: PackedEnum) void { | |
| 697 | testPackedStuff(PackedStruct { | |
| 698 | .a = 1, | |
| 699 | .b = 2, | |
| 700 | }, PackedUnion { | |
| 701 | .a = 1, | |
| 702 | }, PackedEnum.A); | |
| 652 | 703 | } |
| 653 | 704 | |
| 705 | export fn testPackedStuff(a: &const PackedStruct, b: &const PackedUnion, c: PackedEnum) void {} | |
| 654 | 706 | |
| 655 | 707 | test "slicing zero length array" { |
| 656 | 708 | const s1 = ""[0..]; |
| ... | ... | @@ -661,7 +713,6 @@ test "slicing zero length array" { |
| 661 | 713 | assert(mem.eql(u32, s2, []u32{})); |
| 662 | 714 | } |
| 663 | 715 | |
| 664 | ||
| 665 | 716 | const addr1 = @ptrCast(&const u8, emptyFn); |
| 666 | 717 | test "comptime cast fn to ptr" { |
| 667 | 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 | 8 | assert(!some_namespace.a_bool); |
| 9 | 9 | } |
| 10 | 10 | } |
| 11 | const some_namespace = switch(builtin.os) { | |
| 11 | const some_namespace = switch (builtin.os) { | |
| 12 | 12 | builtin.Os.linux => @import("a.zig"), |
| 13 | 13 | else => @import("b.zig"), |
| 14 | 14 | }; |
test/cases/null.zig+12-15| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | const assert = @import("std").debug.assert; |
| 2 | 2 | |
| 3 | 3 | test "nullable type" { |
| 4 | const x : ?bool = true; | |
| 4 | const x: ?bool = true; | |
| 5 | 5 | |
| 6 | 6 | if (x) |y| { |
| 7 | 7 | if (y) { |
| ... | ... | @@ -13,13 +13,13 @@ test "nullable type" { |
| 13 | 13 | unreachable; |
| 14 | 14 | } |
| 15 | 15 | |
| 16 | const next_x : ?i32 = null; | |
| 16 | const next_x: ?i32 = null; | |
| 17 | 17 | |
| 18 | 18 | const z = next_x ?? 1234; |
| 19 | 19 | |
| 20 | 20 | assert(z == 1234); |
| 21 | 21 | |
| 22 | const final_x : ?i32 = 13; | |
| 22 | const final_x: ?i32 = 13; | |
| 23 | 23 | |
| 24 | 24 | const num = final_x ?? unreachable; |
| 25 | 25 | |
| ... | ... | @@ -30,19 +30,17 @@ test "test maybe object and get a pointer to the inner value" { |
| 30 | 30 | var maybe_bool: ?bool = true; |
| 31 | 31 | |
| 32 | 32 | if (maybe_bool) |*b| { |
| 33 | *b = false; | |
| 33 | b.* = false; | |
| 34 | 34 | } |
| 35 | 35 | |
| 36 | 36 | assert(??maybe_bool == false); |
| 37 | 37 | } |
| 38 | 38 | |
| 39 | ||
| 40 | 39 | test "rhs maybe unwrap return" { |
| 41 | 40 | const x: ?bool = true; |
| 42 | 41 | const y = x ?? return; |
| 43 | 42 | } |
| 44 | 43 | |
| 45 | ||
| 46 | 44 | test "maybe return" { |
| 47 | 45 | maybeReturnImpl(); |
| 48 | 46 | comptime maybeReturnImpl(); |
| ... | ... | @@ -50,8 +48,7 @@ test "maybe return" { |
| 50 | 48 | |
| 51 | 49 | fn maybeReturnImpl() void { |
| 52 | 50 | assert(??foo(1235)); |
| 53 | if (foo(null) != null) | |
| 54 | unreachable; | |
| 51 | if (foo(null) != null) unreachable; | |
| 55 | 52 | assert(!??foo(1234)); |
| 56 | 53 | } |
| 57 | 54 | |
| ... | ... | @@ -60,12 +57,16 @@ fn foo(x: ?i32) ?bool { |
| 60 | 57 | return value > 1234; |
| 61 | 58 | } |
| 62 | 59 | |
| 63 | ||
| 64 | 60 | test "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 | } |
| 67 | 68 | fn shouldBeAPlus1(p: &const Particle) u64 { |
| 68 | var maybe_particle: ?Particle = *p; | |
| 69 | var maybe_particle: ?Particle = p.*; | |
| 69 | 70 | if (maybe_particle) |*particle| { |
| 70 | 71 | particle.a += 1; |
| 71 | 72 | } |
| ... | ... | @@ -81,7 +82,6 @@ const Particle = struct { |
| 81 | 82 | d: u64, |
| 82 | 83 | }; |
| 83 | 84 | |
| 84 | ||
| 85 | 85 | test "null literal outside function" { |
| 86 | 86 | const is_null = here_is_a_null_literal.context == null; |
| 87 | 87 | assert(is_null); |
| ... | ... | @@ -96,7 +96,6 @@ const here_is_a_null_literal = SillyStruct { |
| 96 | 96 | .context = null, |
| 97 | 97 | }; |
| 98 | 98 | |
| 99 | ||
| 100 | 99 | test "test null runtime" { |
| 101 | 100 | testTestNullRuntime(null); |
| 102 | 101 | } |
| ... | ... | @@ -123,8 +122,6 @@ fn bar(x: ?void) ?void { |
| 123 | 122 | } |
| 124 | 123 | } |
| 125 | 124 | |
| 126 | ||
| 127 | ||
| 128 | 125 | const StructWithNullable = struct { |
| 129 | 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 | 23 | if (c) { |
| 24 | 24 | const output_path = b; |
| 25 | 25 | |
| 26 | if (c2) { } | |
| 26 | if (c2) {} | |
| 27 | 27 | |
| 28 | 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 | 23 | } |
| 24 | 24 | } |
| 25 | 25 | |
| 26 | fn dummy(a: bool, b: i32, c: f32) i32 { return 1234; } | |
| 26 | fn dummy(a: bool, b: i32, c: f32) i32 { | |
| 27 | return 1234; | |
| 28 | } | |
| 27 | 29 | fn dummy_varargs(args: ...) void {} |
| 28 | 30 | |
| 29 | 31 | test "reflection: struct member types and names" { |
| ... | ... | @@ -54,7 +56,6 @@ test "reflection: enum member types and names" { |
| 54 | 56 | assert(mem.eql(u8, @memberName(Bar, 2), "Three")); |
| 55 | 57 | assert(mem.eql(u8, @memberName(Bar, 3), "Four")); |
| 56 | 58 | } |
| 57 | ||
| 58 | 59 | } |
| 59 | 60 | |
| 60 | 61 | test "reflection: @field" { |
test/cases/slice.zig+6-2| ... | ... | @@ -18,7 +18,11 @@ test "slice child property" { |
| 18 | 18 | } |
| 19 | 19 | |
| 20 | 20 | test "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 | 26 | assert(mem.eql(u8, sliceFromLenToLen(an_array[0..], 3, 3), "")); |
| 23 | 27 | } |
| 24 | 28 | |
| ... | ... | @@ -27,7 +31,7 @@ fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) []u8 { |
| 27 | 31 | } |
| 28 | 32 | |
| 29 | 33 | test "implicitly cast array of size 0 to slice" { |
| 30 | var msg = []u8 {}; | |
| 34 | var msg = []u8{}; | |
| 31 | 35 | assertLenIsZero(msg); |
| 32 | 36 | } |
| 33 | 37 |
test/cases/struct.zig+48-35| ... | ... | @@ -2,9 +2,11 @@ const assert = @import("std").debug.assert; |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | 3 | |
| 4 | 4 | const 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 | }; |
| 7 | const empty_global_instance = StructWithNoFields {}; | |
| 9 | const empty_global_instance = StructWithNoFields{}; | |
| 8 | 10 | |
| 9 | 11 | test "call struct static method" { |
| 10 | 12 | const result = StructWithNoFields.add(3, 4); |
| ... | ... | @@ -34,12 +36,11 @@ test "void struct fields" { |
| 34 | 36 | assert(@sizeOf(VoidStructFieldsFoo) == 4); |
| 35 | 37 | } |
| 36 | 38 | const VoidStructFieldsFoo = struct { |
| 37 | a : void, | |
| 38 | b : i32, | |
| 39 | c : void, | |
| 39 | a: void, | |
| 40 | b: i32, | |
| 41 | c: void, | |
| 40 | 42 | }; |
| 41 | 43 | |
| 42 | ||
| 43 | 44 | test "structs" { |
| 44 | 45 | var foo: StructFoo = undefined; |
| 45 | 46 | @memset(@ptrCast(&u8, &foo), 0, @sizeOf(StructFoo)); |
| ... | ... | @@ -50,9 +51,9 @@ test "structs" { |
| 50 | 51 | assert(foo.c == 100); |
| 51 | 52 | } |
| 52 | 53 | const StructFoo = struct { |
| 53 | a : i32, | |
| 54 | b : bool, | |
| 55 | c : f32, | |
| 54 | a: i32, | |
| 55 | b: bool, | |
| 56 | c: f32, | |
| 56 | 57 | }; |
| 57 | 58 | fn testFoo(foo: &const StructFoo) void { |
| 58 | 59 | assert(foo.b); |
| ... | ... | @@ -61,7 +62,6 @@ fn testMutation(foo: &StructFoo) void { |
| 61 | 62 | foo.c = 100; |
| 62 | 63 | } |
| 63 | 64 | |
| 64 | ||
| 65 | 65 | const Node = struct { |
| 66 | 66 | val: Val, |
| 67 | 67 | next: &Node, |
| ... | ... | @@ -72,10 +72,10 @@ const Val = struct { |
| 72 | 72 | }; |
| 73 | 73 | |
| 74 | 74 | test "struct point to self" { |
| 75 | var root : Node = undefined; | |
| 75 | var root: Node = undefined; | |
| 76 | 76 | root.val.x = 1; |
| 77 | 77 | |
| 78 | var node : Node = undefined; | |
| 78 | var node: Node = undefined; | |
| 79 | 79 | node.next = &root; |
| 80 | 80 | node.val.x = 2; |
| 81 | 81 | |
| ... | ... | @@ -85,8 +85,8 @@ test "struct point to self" { |
| 85 | 85 | } |
| 86 | 86 | |
| 87 | 87 | test "struct byval assign" { |
| 88 | var foo1 : StructFoo = undefined; | |
| 89 | var foo2 : StructFoo = undefined; | |
| 88 | var foo1: StructFoo = undefined; | |
| 89 | var foo2: StructFoo = undefined; | |
| 90 | 90 | |
| 91 | 91 | foo1.a = 1234; |
| 92 | 92 | foo2.a = 0; |
| ... | ... | @@ -96,46 +96,57 @@ test "struct byval assign" { |
| 96 | 96 | } |
| 97 | 97 | |
| 98 | 98 | fn structInitializer() void { |
| 99 | const val = Val { .x = 42 }; | |
| 99 | const val = Val { | |
| 100 | .x = 42, | |
| 101 | }; | |
| 100 | 102 | assert(val.x == 42); |
| 101 | 103 | } |
| 102 | 104 | |
| 103 | ||
| 104 | 105 | test "fn call of struct field" { |
| 105 | assert(callStructField(Foo {.ptr = aFunc,}) == 13); | |
| 106 | assert(callStructField(Foo { | |
| 107 | .ptr = aFunc, | |
| 108 | }) == 13); | |
| 106 | 109 | } |
| 107 | 110 | |
| 108 | 111 | const Foo = struct { |
| 109 | 112 | ptr: fn() i32, |
| 110 | 113 | }; |
| 111 | 114 | |
| 112 | fn aFunc() i32 { return 13; } | |
| 115 | fn aFunc() i32 { | |
| 116 | return 13; | |
| 117 | } | |
| 113 | 118 | |
| 114 | 119 | fn callStructField(foo: &const Foo) i32 { |
| 115 | 120 | return foo.ptr(); |
| 116 | 121 | } |
| 117 | 122 | |
| 118 | ||
| 119 | 123 | test "store member function in variable" { |
| 120 | const instance = MemberFnTestFoo { .x = 1234, }; | |
| 124 | const instance = MemberFnTestFoo { | |
| 125 | .x = 1234, | |
| 126 | }; | |
| 121 | 127 | const memberFn = MemberFnTestFoo.member; |
| 122 | 128 | const result = memberFn(instance); |
| 123 | 129 | assert(result == 1234); |
| 124 | 130 | } |
| 125 | 131 | const MemberFnTestFoo = struct { |
| 126 | 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 | }; |
| 129 | 137 | |
| 130 | ||
| 131 | 138 | test "call member function directly" { |
| 132 | const instance = MemberFnTestFoo { .x = 1234, }; | |
| 139 | const instance = MemberFnTestFoo { | |
| 140 | .x = 1234, | |
| 141 | }; | |
| 133 | 142 | const result = MemberFnTestFoo.member(instance); |
| 134 | 143 | assert(result == 1234); |
| 135 | 144 | } |
| 136 | 145 | |
| 137 | 146 | test "member functions" { |
| 138 | const r = MemberFnRand {.seed = 1234}; | |
| 147 | const r = MemberFnRand { | |
| 148 | .seed = 1234, | |
| 149 | }; | |
| 139 | 150 | assert(r.getSeed() == 1234); |
| 140 | 151 | } |
| 141 | 152 | const MemberFnRand = struct { |
| ... | ... | @@ -170,17 +181,16 @@ const EmptyStruct = struct { |
| 170 | 181 | } |
| 171 | 182 | }; |
| 172 | 183 | |
| 173 | ||
| 174 | 184 | test "return empty struct from fn" { |
| 175 | 185 | _ = testReturnEmptyStructFromFn(); |
| 176 | 186 | } |
| 177 | 187 | const EmptyStruct2 = struct {}; |
| 178 | 188 | fn testReturnEmptyStructFromFn() EmptyStruct2 { |
| 179 | return EmptyStruct2 {}; | |
| 189 | return EmptyStruct2{}; | |
| 180 | 190 | } |
| 181 | 191 | |
| 182 | 192 | test "pass slice of empty struct to fn" { |
| 183 | assert(testPassSliceOfEmptyStructToFn([]EmptyStruct2{ EmptyStruct2{} }) == 1); | |
| 193 | assert(testPassSliceOfEmptyStructToFn([]EmptyStruct2 {EmptyStruct2{}}) == 1); | |
| 184 | 194 | } |
| 185 | 195 | fn testPassSliceOfEmptyStructToFn(slice: []const EmptyStruct2) usize { |
| 186 | 196 | return slice.len; |
| ... | ... | @@ -201,7 +211,6 @@ test "packed struct" { |
| 201 | 211 | assert(four == 4); |
| 202 | 212 | } |
| 203 | 213 | |
| 204 | ||
| 205 | 214 | const BitField1 = packed struct { |
| 206 | 215 | a: u3, |
| 207 | 216 | b: u3, |
| ... | ... | @@ -301,7 +310,7 @@ test "packed array 24bits" { |
| 301 | 310 | assert(@sizeOf(FooArray24Bits) == 2 + 2 * 3 + 2); |
| 302 | 311 | } |
| 303 | 312 | |
| 304 | var bytes = []u8{0} ** (@sizeOf(FooArray24Bits) + 1); | |
| 313 | var bytes = []u8 {0} ** (@sizeOf(FooArray24Bits) + 1); | |
| 305 | 314 | bytes[bytes.len - 1] = 0xaa; |
| 306 | 315 | const ptr = &([]FooArray24Bits)(bytes[0..bytes.len - 1])[0]; |
| 307 | 316 | assert(ptr.a == 0); |
| ... | ... | @@ -351,7 +360,7 @@ test "aligned array of packed struct" { |
| 351 | 360 | assert(@sizeOf(FooArrayOfAligned) == 2 * 2); |
| 352 | 361 | } |
| 353 | 362 | |
| 354 | var bytes = []u8{0xbb} ** @sizeOf(FooArrayOfAligned); | |
| 363 | var bytes = []u8 {0xbb} ** @sizeOf(FooArrayOfAligned); | |
| 355 | 364 | const ptr = &([]FooArrayOfAligned)(bytes[0..bytes.len])[0]; |
| 356 | 365 | |
| 357 | 366 | assert(ptr.a[0].a == 0xbb); |
| ... | ... | @@ -360,11 +369,15 @@ test "aligned array of packed struct" { |
| 360 | 369 | assert(ptr.a[1].b == 0xbb); |
| 361 | 370 | } |
| 362 | 371 | |
| 363 | ||
| 364 | ||
| 365 | 372 | test "runtime struct initialization of bitfield" { |
| 366 | const s1 = Nibbles { .x = x1, .y = x1 }; | |
| 367 | const s2 = Nibbles { .x = u4(x2), .y = u4(x2) }; | |
| 373 | const s1 = Nibbles { | |
| 374 | .x = x1, | |
| 375 | .y = x1, | |
| 376 | }; | |
| 377 | const s2 = Nibbles { | |
| 378 | .x = u4(x2), | |
| 379 | .y = u4(x2), | |
| 380 | }; | |
| 368 | 381 | |
| 369 | 382 | assert(s1.x == x1); |
| 370 | 383 | assert(s1.y == x1); |
| ... | ... | @@ -394,7 +407,7 @@ test "native bit field understands endianness" { |
| 394 | 407 | var all: u64 = 0x7765443322221111; |
| 395 | 408 | var bytes: [8]u8 = undefined; |
| 396 | 409 | @memcpy(&bytes[0], @ptrCast(&u8, &all), 8); |
| 397 | var bitfields = *@ptrCast(&Bitfields, &bytes[0]); | |
| 410 | var bitfields = @ptrCast(&Bitfields, &bytes[0]).*; | |
| 398 | 411 | |
| 399 | 412 | assert(bitfields.f1 == 0x1111); |
| 400 | 413 | assert(bitfields.f2 == 0x2222); |
test/cases/struct_contains_null_ptr_itself.zig-1| ... | ... | @@ -19,4 +19,3 @@ pub const Node = struct { |
| 19 | 19 | pub const NodeLineComment = struct { |
| 20 | 20 | base: Node, |
| 21 | 21 | }; |
| 22 |
test/cases/struct_contains_slice_of_itself.zig+1-1| ... | ... | @@ -6,7 +6,7 @@ const Node = struct { |
| 6 | 6 | }; |
| 7 | 7 | |
| 8 | 8 | test "struct contains slice of itself" { |
| 9 | var other_nodes = []Node{ | |
| 9 | var other_nodes = []Node { | |
| 10 | 10 | Node { |
| 11 | 11 | .payload = 31, |
| 12 | 12 | .children = []Node{}, |
test/cases/switch.zig+33-16| ... | ... | @@ -6,7 +6,10 @@ test "switch with numbers" { |
| 6 | 6 | |
| 7 | 7 | fn testSwitchWithNumbers(x: u32) void { |
| 8 | 8 | const result = switch (x) { |
| 9 | 1, 2, 3, 4 ... 8 => false, | |
| 9 | 1, | |
| 10 | 2, | |
| 11 | 3, | |
| 12 | 4 ... 8 => false, | |
| 10 | 13 | 13 => true, |
| 11 | 14 | else => false, |
| 12 | 15 | }; |
| ... | ... | @@ -34,8 +37,10 @@ test "implicit comptime switch" { |
| 34 | 37 | const result = switch (x) { |
| 35 | 38 | 3 => 10, |
| 36 | 39 | 4 => 11, |
| 37 | 5, 6 => 12, | |
| 38 | 7, 8 => 13, | |
| 40 | 5, | |
| 41 | 6 => 12, | |
| 42 | 7, | |
| 43 | 8 => 13, | |
| 39 | 44 | else => 14, |
| 40 | 45 | }; |
| 41 | 46 | |
| ... | ... | @@ -61,7 +66,6 @@ fn nonConstSwitchOnEnum(fruit: Fruit) void { |
| 61 | 66 | } |
| 62 | 67 | } |
| 63 | 68 | |
| 64 | ||
| 65 | 69 | test "switch statement" { |
| 66 | 70 | nonConstSwitch(SwitchStatmentFoo.C); |
| 67 | 71 | } |
| ... | ... | @@ -81,11 +85,16 @@ const SwitchStatmentFoo = enum { |
| 81 | 85 | D, |
| 82 | 86 | }; |
| 83 | 87 | |
| 84 | ||
| 85 | 88 | test "switch prong with variable" { |
| 86 | switchProngWithVarFn(SwitchProngWithVarEnum { .One = 13}); | |
| 87 | switchProngWithVarFn(SwitchProngWithVarEnum { .Two = 13.0}); | |
| 88 | switchProngWithVarFn(SwitchProngWithVarEnum { .Meh = {}}); | |
| 89 | switchProngWithVarFn(SwitchProngWithVarEnum { | |
| 90 | .One = 13, | |
| 91 | }); | |
| 92 | switchProngWithVarFn(SwitchProngWithVarEnum { | |
| 93 | .Two = 13.0, | |
| 94 | }); | |
| 95 | switchProngWithVarFn(SwitchProngWithVarEnum { | |
| 96 | .Meh = {}, | |
| 97 | }); | |
| 89 | 98 | } |
| 90 | 99 | const SwitchProngWithVarEnum = union(enum) { |
| 91 | 100 | One: i32, |
| ... | ... | @@ -93,7 +102,7 @@ const SwitchProngWithVarEnum = union(enum) { |
| 93 | 102 | Meh: void, |
| 94 | 103 | }; |
| 95 | 104 | fn switchProngWithVarFn(a: &const SwitchProngWithVarEnum) void { |
| 96 | switch(*a) { | |
| 105 | switch (a.*) { | |
| 97 | 106 | SwitchProngWithVarEnum.One => |x| { |
| 98 | 107 | assert(x == 13); |
| 99 | 108 | }, |
| ... | ... | @@ -112,9 +121,11 @@ test "switch on enum using pointer capture" { |
| 112 | 121 | } |
| 113 | 122 | |
| 114 | 123 | fn testSwitchEnumPtrCapture() void { |
| 115 | var value = SwitchProngWithVarEnum { .One = 1234 }; | |
| 124 | var value = SwitchProngWithVarEnum { | |
| 125 | .One = 1234, | |
| 126 | }; | |
| 116 | 127 | switch (value) { |
| 117 | SwitchProngWithVarEnum.One => |*x| *x += 1, | |
| 128 | SwitchProngWithVarEnum.One => |*x| x.* += 1, | |
| 118 | 129 | else => unreachable, |
| 119 | 130 | } |
| 120 | 131 | switch (value) { |
| ... | ... | @@ -125,8 +136,12 @@ fn testSwitchEnumPtrCapture() void { |
| 125 | 136 | |
| 126 | 137 | test "switch with multiple expressions" { |
| 127 | 138 | const x = switch (returnsFive()) { |
| 128 | 1, 2, 3 => 1, | |
| 129 | 4, 5, 6 => 2, | |
| 139 | 1, | |
| 140 | 2, | |
| 141 | 3 => 1, | |
| 142 | 4, | |
| 143 | 5, | |
| 144 | 6 => 2, | |
| 130 | 145 | else => i32(3), |
| 131 | 146 | }; |
| 132 | 147 | assert(x == 2); |
| ... | ... | @@ -135,14 +150,15 @@ fn returnsFive() i32 { |
| 135 | 150 | return 5; |
| 136 | 151 | } |
| 137 | 152 | |
| 138 | ||
| 139 | 153 | const Number = union(enum) { |
| 140 | 154 | One: u64, |
| 141 | 155 | Two: u8, |
| 142 | 156 | Three: f32, |
| 143 | 157 | }; |
| 144 | 158 | |
| 145 | const number = Number { .Three = 1.23 }; | |
| 159 | const number = Number { | |
| 160 | .Three = 1.23, | |
| 161 | }; | |
| 146 | 162 | |
| 147 | 163 | fn returnsFalse() bool { |
| 148 | 164 | switch (number) { |
| ... | ... | @@ -198,7 +214,8 @@ fn testSwitchHandleAllCasesRange(x: u8) u8 { |
| 198 | 214 | return switch (x) { |
| 199 | 215 | 0 ... 100 => u8(0), |
| 200 | 216 | 101 ... 200 => 1, |
| 201 | 201, 203 => 2, | |
| 217 | 201, | |
| 218 | 203 => 2, | |
| 202 | 219 | 202 => 4, |
| 203 | 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 | |
| 15 | 15 | fn doThing(form_id: u64) error!FormValue { |
| 16 | 16 | return switch (form_id) { |
| 17 | 17 => FormValue { .Address = try readOnce() }, | |
| 17 | 17 => FormValue { | |
| 18 | .Address = try readOnce(), | |
| 19 | }, | |
| 18 | 20 | else => error.InvalidDebugInfo, |
| 19 | 21 | }; |
| 20 | 22 | } |
| 21 | 23 | |
| 22 | 24 | test "switch prong returns error enum" { |
| 23 | 25 | switch (doThing(17) catch unreachable) { |
| 24 | FormValue.Address => |payload| { assert(payload == 1); }, | |
| 26 | FormValue.Address => |payload| { | |
| 27 | assert(payload == 1); | |
| 28 | }, | |
| 25 | 29 | else => unreachable, |
| 26 | 30 | } |
| 27 | 31 | assert(read_count == 1); |
test/cases/switch_prong_implicit_cast.zig+6-2| ... | ... | @@ -7,8 +7,12 @@ const FormValue = union(enum) { |
| 7 | 7 | |
| 8 | 8 | fn foo(id: u64) !FormValue { |
| 9 | 9 | return switch (id) { |
| 10 | 2 => FormValue { .Two = true }, | |
| 11 | 1 => FormValue { .One = {} }, | |
| 10 | 2 => FormValue { | |
| 11 | .Two = true, | |
| 12 | }, | |
| 13 | 1 => FormValue { | |
| 14 | .One = {}, | |
| 15 | }, | |
| 12 | 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 | 3 | test "try on error union" { |
| 4 | 4 | tryOnErrorUnionImpl(); |
| 5 | 5 | comptime tryOnErrorUnionImpl(); |
| 6 | ||
| 7 | 6 | } |
| 8 | 7 | |
| 9 | 8 | fn tryOnErrorUnionImpl() void { |
| 10 | const x = if (returnsTen()) |val| | |
| 11 | val + 1 | |
| 12 | else |err| switch (err) { | |
| 13 | error.ItBroke, error.NoMem => 1, | |
| 9 | const x = if (returnsTen()) |val| val + 1 else |err| switch (err) { | |
| 10 | error.ItBroke, | |
| 11 | error.NoMem => 1, | |
| 14 | 12 | error.CrappedOut => i32(2), |
| 15 | 13 | else => unreachable, |
| 16 | 14 | }; |
test/cases/undefined.zig+2-2| ... | ... | @@ -63,6 +63,6 @@ test "assign undefined to struct with method" { |
| 63 | 63 | } |
| 64 | 64 | |
| 65 | 65 | test "type name of undefined" { |
| 66 | const x = undefined; | |
| 67 | assert(mem.eql(u8, @typeName(@typeOf(x)), "(undefined)")); | |
| 66 | const 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 | 10 | val2: Value, |
| 11 | 11 | }; |
| 12 | 12 | |
| 13 | const v1 = Value { .Int = 1234 }; | |
| 14 | const v2 = Value { .Array = []u8{3} ** 9 }; | |
| 13 | const v1 = Value{ .Int = 1234 }; | |
| 14 | const v2 = Value{ .Array = []u8{3} ** 9 }; | |
| 15 | 15 | |
| 16 | const err = (error!Agg)(Agg { | |
| 16 | const err = (error!Agg)(Agg{ | |
| 17 | 17 | .val1 = v1, |
| 18 | 18 | .val2 = v2, |
| 19 | 19 | }); |
| 20 | 20 | |
| 21 | const array = []Value { v1, v2, v1, v2}; | |
| 22 | ||
| 21 | const array = []Value{ | |
| 22 | v1, | |
| 23 | v2, | |
| 24 | v1, | |
| 25 | v2, | |
| 26 | }; | |
| 23 | 27 | |
| 24 | 28 | test "unions embedded in aggregate types" { |
| 25 | 29 | switch (array[1]) { |
| 26 | 30 | Value.Array => |arr| assert(arr[4] == 3), |
| 27 | 31 | else => unreachable, |
| 28 | 32 | } |
| 29 | switch((err catch unreachable).val1) { | |
| 33 | switch ((err catch unreachable).val1) { | |
| 30 | 34 | Value.Int => |x| assert(x == 1234), |
| 31 | 35 | else => unreachable, |
| 32 | 36 | } |
| 33 | 37 | } |
| 34 | 38 | |
| 35 | ||
| 36 | 39 | const Foo = union { |
| 37 | 40 | float: f64, |
| 38 | 41 | int: i32, |
| 39 | 42 | }; |
| 40 | 43 | |
| 41 | 44 | test "basic unions" { |
| 42 | var foo = Foo { .int = 1 }; | |
| 45 | var foo = Foo{ .int = 1 }; | |
| 43 | 46 | assert(foo.int == 1); |
| 44 | foo = Foo {.float = 12.34}; | |
| 47 | foo = Foo{ .float = 12.34 }; | |
| 45 | 48 | assert(foo.float == 12.34); |
| 46 | 49 | } |
| 47 | 50 | |
| ... | ... | @@ -56,11 +59,11 @@ test "init union with runtime value" { |
| 56 | 59 | } |
| 57 | 60 | |
| 58 | 61 | fn setFloat(foo: &Foo, x: f64) void { |
| 59 | *foo = Foo { .float = x }; | |
| 62 | foo.* = Foo{ .float = x }; | |
| 60 | 63 | } |
| 61 | 64 | |
| 62 | 65 | fn setInt(foo: &Foo, x: i32) void { |
| 63 | *foo = Foo { .int = x }; | |
| 66 | foo.* = Foo{ .int = x }; | |
| 64 | 67 | } |
| 65 | 68 | |
| 66 | 69 | const FooExtern = extern union { |
| ... | ... | @@ -69,13 +72,12 @@ const FooExtern = extern union { |
| 69 | 72 | }; |
| 70 | 73 | |
| 71 | 74 | test "basic extern unions" { |
| 72 | var foo = FooExtern { .int = 1 }; | |
| 75 | var foo = FooExtern{ .int = 1 }; | |
| 73 | 76 | assert(foo.int == 1); |
| 74 | 77 | foo.float = 12.34; |
| 75 | 78 | assert(foo.float == 12.34); |
| 76 | 79 | } |
| 77 | 80 | |
| 78 | ||
| 79 | 81 | const Letter = enum { |
| 80 | 82 | A, |
| 81 | 83 | B, |
| ... | ... | @@ -93,12 +95,12 @@ test "union with specified enum tag" { |
| 93 | 95 | } |
| 94 | 96 | |
| 95 | 97 | fn doTest() void { |
| 96 | assert(bar(Payload {.A = 1234}) == -10); | |
| 98 | assert(bar(Payload{ .A = 1234 }) == -10); | |
| 97 | 99 | } |
| 98 | 100 | |
| 99 | 101 | fn bar(value: &const Payload) i32 { |
| 100 | assert(Letter(*value) == Letter.A); | |
| 101 | return switch (*value) { | |
| 102 | assert(Letter(value.*) == Letter.A); | |
| 103 | return switch (value.*) { | |
| 102 | 104 | Payload.A => |x| return x - 1244, |
| 103 | 105 | Payload.B => |x| if (x == 12.34) i32(20) else 21, |
| 104 | 106 | Payload.C => |x| if (x) i32(30) else 31, |
| ... | ... | @@ -131,13 +133,13 @@ const MultipleChoice2 = union(enum(u32)) { |
| 131 | 133 | |
| 132 | 134 | test "union(enum(u32)) with specified and unspecified tag values" { |
| 133 | 135 | comptime assert(@TagType(@TagType(MultipleChoice2)) == u32); |
| 134 | testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2 {.C = 123}); | |
| 135 | comptime testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2 { .C = 123} ); | |
| 136 | testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2{ .C = 123 }); | |
| 137 | comptime testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2{ .C = 123 }); | |
| 136 | 138 | } |
| 137 | 139 | |
| 138 | 140 | fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: &const MultipleChoice2) void { |
| 139 | assert(u32(@TagType(MultipleChoice2)(*x)) == 60); | |
| 140 | assert(1123 == switch (*x) { | |
| 141 | assert(u32(@TagType(MultipleChoice2)(x.*)) == 60); | |
| 142 | assert(1123 == switch (x.*) { | |
| 141 | 143 | MultipleChoice2.A => 1, |
| 142 | 144 | MultipleChoice2.B => 2, |
| 143 | 145 | MultipleChoice2.C => |v| i32(1000) + v, |
| ... | ... | @@ -150,10 +152,9 @@ fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: &const MultipleChoice2) void |
| 150 | 152 | }); |
| 151 | 153 | } |
| 152 | 154 | |
| 153 | ||
| 154 | 155 | const ExternPtrOrInt = extern union { |
| 155 | 156 | ptr: &u8, |
| 156 | int: u64 | |
| 157 | int: u64, | |
| 157 | 158 | }; |
| 158 | 159 | test "extern union size" { |
| 159 | 160 | comptime assert(@sizeOf(ExternPtrOrInt) == 8); |
| ... | ... | @@ -161,7 +162,7 @@ test "extern union size" { |
| 161 | 162 | |
| 162 | 163 | const PackedPtrOrInt = packed union { |
| 163 | 164 | ptr: &u8, |
| 164 | int: u64 | |
| 165 | int: u64, | |
| 165 | 166 | }; |
| 166 | 167 | test "extern union size" { |
| 167 | 168 | comptime assert(@sizeOf(PackedPtrOrInt) == 8); |
| ... | ... | @@ -174,8 +175,16 @@ test "union with only 1 field which is void should be zero bits" { |
| 174 | 175 | comptime assert(@sizeOf(ZeroBits) == 0); |
| 175 | 176 | } |
| 176 | 177 | |
| 177 | const TheTag = enum {A, B, C}; | |
| 178 | const TheUnion = union(TheTag) { A: i32, B: i32, C: i32 }; | |
| 178 | const TheTag = enum { | |
| 179 | A, | |
| 180 | B, | |
| 181 | C, | |
| 182 | }; | |
| 183 | const TheUnion = union(TheTag) { | |
| 184 | A: i32, | |
| 185 | B: i32, | |
| 186 | C: i32, | |
| 187 | }; | |
| 179 | 188 | test "union field access gives the enum values" { |
| 180 | 189 | assert(TheUnion.A == TheTag.A); |
| 181 | 190 | assert(TheUnion.B == TheTag.B); |
| ... | ... | @@ -183,20 +192,28 @@ test "union field access gives the enum values" { |
| 183 | 192 | } |
| 184 | 193 | |
| 185 | 194 | test "cast union to tag type of union" { |
| 186 | testCastUnionToTagType(TheUnion {.B = 1234}); | |
| 187 | comptime testCastUnionToTagType(TheUnion {.B = 1234}); | |
| 195 | testCastUnionToTagType(TheUnion{ .B = 1234 }); | |
| 196 | comptime testCastUnionToTagType(TheUnion{ .B = 1234 }); | |
| 188 | 197 | } |
| 189 | 198 | |
| 190 | 199 | fn testCastUnionToTagType(x: &const TheUnion) void { |
| 191 | assert(TheTag(*x) == TheTag.B); | |
| 200 | assert(TheTag(x.*) == TheTag.B); | |
| 192 | 201 | } |
| 193 | 202 | |
| 194 | 203 | test "cast tag type of union to union" { |
| 195 | 204 | var x: Value2 = Letter2.B; |
| 196 | 205 | assert(Letter2(x) == Letter2.B); |
| 197 | 206 | } |
| 198 | const Letter2 = enum { A, B, C }; | |
| 199 | const Value2 = union(Letter2) { A: i32, B, C, }; | |
| 207 | const Letter2 = enum { | |
| 208 | A, | |
| 209 | B, | |
| 210 | C, | |
| 211 | }; | |
| 212 | const Value2 = union(Letter2) { | |
| 213 | A: i32, | |
| 214 | B, | |
| 215 | C, | |
| 216 | }; | |
| 200 | 217 | |
| 201 | 218 | test "implicit cast union to its tag type" { |
| 202 | 219 | var x: Value2 = Letter2.B; |
| ... | ... | @@ -217,19 +234,16 @@ const TheUnion2 = union(enum) { |
| 217 | 234 | }; |
| 218 | 235 | |
| 219 | 236 | fn assertIsTheUnion2Item1(value: &const TheUnion2) void { |
| 220 | assert(*value == TheUnion2.Item1); | |
| 237 | assert(value.* == TheUnion2.Item1); | |
| 221 | 238 | } |
| 222 | 239 | |
| 223 | ||
| 224 | 240 | pub const PackThis = union(enum) { |
| 225 | 241 | Invalid: bool, |
| 226 | 242 | StringLiteral: u2, |
| 227 | 243 | }; |
| 228 | 244 | |
| 229 | 245 | test "constant packed union" { |
| 230 | testConstPackedUnion([]PackThis { | |
| 231 | PackThis { .StringLiteral = 1 }, | |
| 232 | }); | |
| 246 | testConstPackedUnion([]PackThis{PackThis{ .StringLiteral = 1 }}); | |
| 233 | 247 | } |
| 234 | 248 | |
| 235 | 249 | fn testConstPackedUnion(expected_tokens: []const PackThis) void { |
| ... | ... | @@ -242,7 +256,7 @@ test "switch on union with only 1 field" { |
| 242 | 256 | switch (r) { |
| 243 | 257 | PartialInst.Compiled => { |
| 244 | 258 | var z: PartialInstWithPayload = undefined; |
| 245 | z = PartialInstWithPayload { .Compiled = 1234 }; | |
| 259 | z = PartialInstWithPayload{ .Compiled = 1234 }; | |
| 246 | 260 | switch (z) { |
| 247 | 261 | PartialInstWithPayload.Compiled => |x| { |
| 248 | 262 | assert(x == 1234); |
| ... | ... | @@ -261,4 +275,3 @@ const PartialInst = union(enum) { |
| 261 | 275 | const PartialInstWithPayload = union(enum) { |
| 262 | 276 | Compiled: i32, |
| 263 | 277 | }; |
| 264 |
test/cases/var_args.zig+16-9| ... | ... | @@ -2,9 +2,12 @@ const assert = @import("std").debug.assert; |
| 2 | 2 | |
| 3 | 3 | fn add(args: ...) i32 { |
| 4 | 4 | var sum = i32(0); |
| 5 | {comptime var i: usize = 0; inline while (i < args.len) : (i += 1) { | |
| 6 | sum += args[i]; | |
| 7 | }} | |
| 5 | { | |
| 6 | comptime var i: usize = 0; | |
| 7 | inline while (i < args.len) : (i += 1) { | |
| 8 | sum += args[i]; | |
| 9 | } | |
| 10 | } | |
| 8 | 11 | return sum; |
| 9 | 12 | } |
| 10 | 13 | |
| ... | ... | @@ -55,18 +58,23 @@ fn extraFn(extra: u32, args: ...) usize { |
| 55 | 58 | return args.len; |
| 56 | 59 | } |
| 57 | 60 | |
| 61 | const foos = []fn(...) bool { | |
| 62 | foo1, | |
| 63 | foo2, | |
| 64 | }; | |
| 58 | 65 | |
| 59 | const foos = []fn(...) bool { foo1, foo2 }; | |
| 60 | ||
| 61 | fn foo1(args: ...) bool { return true; } | |
| 62 | fn foo2(args: ...) bool { return false; } | |
| 66 | fn foo1(args: ...) bool { | |
| 67 | return true; | |
| 68 | } | |
| 69 | fn foo2(args: ...) bool { | |
| 70 | return false; | |
| 71 | } | |
| 63 | 72 | |
| 64 | 73 | test "array of var args functions" { |
| 65 | 74 | assert(foos[0]()); |
| 66 | 75 | assert(!foos[1]()); |
| 67 | 76 | } |
| 68 | 77 | |
| 69 | ||
| 70 | 78 | test "pass array and slice of same array to var args should have same pointers" { |
| 71 | 79 | const array = "hi"; |
| 72 | 80 | const slice: []const u8 = array; |
| ... | ... | @@ -79,7 +87,6 @@ fn assertSlicePtrsEql(args: ...) void { |
| 79 | 87 | assert(s1.ptr == s2.ptr); |
| 80 | 88 | } |
| 81 | 89 | |
| 82 | ||
| 83 | 90 | test "pass zero length array to var args param" { |
| 84 | 91 | doNothingWithFirstArg(""); |
| 85 | 92 | } |
test/cases/while.zig+41-24| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | const assert = @import("std").debug.assert; |
| 2 | 2 | |
| 3 | 3 | test "while loop" { |
| 4 | var i : i32 = 0; | |
| 4 | var i: i32 = 0; | |
| 5 | 5 | while (i < 4) { |
| 6 | 6 | i += 1; |
| 7 | 7 | } |
| ... | ... | @@ -35,7 +35,7 @@ test "continue and break" { |
| 35 | 35 | } |
| 36 | 36 | var continue_and_break_counter: i32 = 0; |
| 37 | 37 | fn runContinueAndBreakTest() void { |
| 38 | var i : i32 = 0; | |
| 38 | var i: i32 = 0; | |
| 39 | 39 | while (true) { |
| 40 | 40 | continue_and_break_counter += 2; |
| 41 | 41 | i += 1; |
| ... | ... | @@ -58,10 +58,13 @@ fn returnWithImplicitCastFromWhileLoopTest() error!void { |
| 58 | 58 | |
| 59 | 59 | test "while with continue expression" { |
| 60 | 60 | var sum: i32 = 0; |
| 61 | {var i: i32 = 0; while (i < 10) : (i += 1) { | |
| 62 | if (i == 5) continue; | |
| 63 | sum += i; | |
| 64 | }} | |
| 61 | { | |
| 62 | var i: i32 = 0; | |
| 63 | while (i < 10) : (i += 1) { | |
| 64 | if (i == 5) continue; | |
| 65 | sum += i; | |
| 66 | } | |
| 67 | } | |
| 65 | 68 | assert(sum == 40); |
| 66 | 69 | } |
| 67 | 70 | |
| ... | ... | @@ -117,17 +120,13 @@ test "while with error union condition" { |
| 117 | 120 | |
| 118 | 121 | var numbers_left: i32 = undefined; |
| 119 | 122 | fn getNumberOrErr() error!i32 { |
| 120 | return if (numbers_left == 0) | |
| 121 | error.OutOfNumbers | |
| 122 | else x: { | |
| 123 | return if (numbers_left == 0) error.OutOfNumbers else x: { | |
| 123 | 124 | numbers_left -= 1; |
| 124 | 125 | break :x numbers_left; |
| 125 | 126 | }; |
| 126 | 127 | } |
| 127 | 128 | fn getNumberOrNull() ?i32 { |
| 128 | return if (numbers_left == 0) | |
| 129 | null | |
| 130 | else x: { | |
| 129 | return if (numbers_left == 0) null else x: { | |
| 131 | 130 | numbers_left -= 1; |
| 132 | 131 | break :x numbers_left; |
| 133 | 132 | }; |
| ... | ... | @@ -136,42 +135,48 @@ fn getNumberOrNull() ?i32 { |
| 136 | 135 | test "while on nullable with else result follow else prong" { |
| 137 | 136 | const result = while (returnNull()) |value| { |
| 138 | 137 | break value; |
| 139 | } else i32(2); | |
| 138 | } else | |
| 139 | i32(2); | |
| 140 | 140 | assert(result == 2); |
| 141 | 141 | } |
| 142 | 142 | |
| 143 | 143 | test "while on nullable with else result follow break prong" { |
| 144 | 144 | const result = while (returnMaybe(10)) |value| { |
| 145 | 145 | break value; |
| 146 | } else i32(2); | |
| 146 | } else | |
| 147 | i32(2); | |
| 147 | 148 | assert(result == 10); |
| 148 | 149 | } |
| 149 | 150 | |
| 150 | 151 | test "while on error union with else result follow else prong" { |
| 151 | 152 | const result = while (returnError()) |value| { |
| 152 | 153 | break value; |
| 153 | } else |err| i32(2); | |
| 154 | } else|err| | |
| 155 | i32(2); | |
| 154 | 156 | assert(result == 2); |
| 155 | 157 | } |
| 156 | 158 | |
| 157 | 159 | test "while on error union with else result follow break prong" { |
| 158 | 160 | const result = while (returnSuccess(10)) |value| { |
| 159 | 161 | break value; |
| 160 | } else |err| i32(2); | |
| 162 | } else|err| | |
| 163 | i32(2); | |
| 161 | 164 | assert(result == 10); |
| 162 | 165 | } |
| 163 | 166 | |
| 164 | 167 | test "while on bool with else result follow else prong" { |
| 165 | 168 | const result = while (returnFalse()) { |
| 166 | 169 | break i32(10); |
| 167 | } else i32(2); | |
| 170 | } else | |
| 171 | i32(2); | |
| 168 | 172 | assert(result == 2); |
| 169 | 173 | } |
| 170 | 174 | |
| 171 | 175 | test "while on bool with else result follow break prong" { |
| 172 | 176 | const result = while (returnTrue()) { |
| 173 | 177 | break i32(10); |
| 174 | } else i32(2); | |
| 178 | } else | |
| 179 | i32(2); | |
| 175 | 180 | assert(result == 10); |
| 176 | 181 | } |
| 177 | 182 | |
| ... | ... | @@ -202,9 +207,21 @@ fn testContinueOuter() void { |
| 202 | 207 | } |
| 203 | 208 | } |
| 204 | 209 | |
| 205 | fn returnNull() ?i32 { return null; } | |
| 206 | fn returnMaybe(x: i32) ?i32 { return x; } | |
| 207 | fn returnError() error!i32 { return error.YouWantedAnError; } | |
| 208 | fn returnSuccess(x: i32) error!i32 { return x; } | |
| 209 | fn returnFalse() bool { return false; } | |
| 210 | fn returnTrue() bool { return true; } | |
| 210 | fn returnNull() ?i32 { | |
| 211 | return null; | |
| 212 | } | |
| 213 | fn returnMaybe(x: i32) ?i32 { | |
| 214 | return x; | |
| 215 | } | |
| 216 | fn returnError() error!i32 { | |
| 217 | return error.YouWantedAnError; | |
| 218 | } | |
| 219 | fn returnSuccess(x: i32) error!i32 { | |
| 220 | return x; | |
| 221 | } | |
| 222 | fn returnFalse() bool { | |
| 223 | return false; | |
| 224 | } | |
| 225 | fn returnTrue() bool { | |
| 226 | return true; | |
| 227 | } |