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