| author | |
| committer | |
| log | af536ac343564e5120f99cbf3b7fc9efa984eb93 |
| tree | 42a937bca75d34e2d3b4fc7d44ebafa66d8bd55b |
| parent | 329457bb4f714a8392153dfecfabd6f356144688 |
* remove setFnTest builtin
* add test "name" { ... } syntax
* remove --check-unused argument. functions are always lazy now.58 files changed, 617 insertions(+), 880 deletions(-)
doc/langref.md+3-1| ... | ... | @@ -5,7 +5,9 @@ |
| 5 | 5 | ``` |
| 6 | 6 | Root = many(TopLevelItem) "EOF" |
| 7 | 7 | |
| 8 | TopLevelItem = ErrorValueDecl | Block | TopLevelDecl | |
| 8 | TopLevelItem = ErrorValueDecl | Block | TopLevelDecl | TestDecl | |
| 9 | ||
| 10 | TestDecl = "test" String Block | |
| 9 | 11 | |
| 10 | 12 | TopLevelDecl = option(VisibleMod) (FnDef | ExternDecl | GlobalVarDecl | TypeDecl | UseDecl) |
| 11 | 13 |
doc/vim/syntax/zig.vim+1-1| ... | ... | @@ -15,7 +15,7 @@ syn keyword zigConditional if else switch try |
| 15 | 15 | syn keyword zigRepeat while for |
| 16 | 16 | |
| 17 | 17 | syn keyword zigConstant null undefined this |
| 18 | syn keyword zigKeyword fn use | |
| 18 | syn keyword zigKeyword fn use test | |
| 19 | 19 | syn keyword zigType bool f32 f64 void Unreachable type error |
| 20 | 20 | syn keyword zigType i8 u8 i16 u16 i32 u32 i64 u64 isize usize |
| 21 | 21 | syn keyword zigType c_short c_ushort c_int c_uint c_long c_ulong c_longlong c_ulonglong c_long_double |
src/all_types.hpp+12-10| ... | ... | @@ -311,6 +311,7 @@ enum NodeType { |
| 311 | 311 | NodeTypeVariableDeclaration, |
| 312 | 312 | NodeTypeTypeDecl, |
| 313 | 313 | NodeTypeErrorValueDecl, |
| 314 | NodeTypeTestDecl, | |
| 314 | 315 | NodeTypeBinOpExpr, |
| 315 | 316 | NodeTypeUnwrapErrorExpr, |
| 316 | 317 | NodeTypeNumberLiteral, |
| ... | ... | @@ -435,6 +436,14 @@ struct AstNodeErrorValueDecl { |
| 435 | 436 | ErrorTableEntry *err; |
| 436 | 437 | }; |
| 437 | 438 | |
| 439 | struct AstNodeTestDecl { | |
| 440 | // always invalid if it's not VisibModPrivate but can be parsed that way | |
| 441 | VisibMod visib_mod; | |
| 442 | Buf *name; | |
| 443 | ||
| 444 | AstNode *body; | |
| 445 | }; | |
| 446 | ||
| 438 | 447 | enum BinOpType { |
| 439 | 448 | BinOpTypeInvalid, |
| 440 | 449 | BinOpTypeAssign, |
| ... | ... | @@ -781,6 +790,7 @@ struct AstNode { |
| 781 | 790 | AstNodeVariableDeclaration variable_declaration; |
| 782 | 791 | AstNodeTypeDecl type_decl; |
| 783 | 792 | AstNodeErrorValueDecl error_value_decl; |
| 793 | AstNodeTestDecl test_decl; | |
| 784 | 794 | AstNodeBinOpExpr bin_op_expr; |
| 785 | 795 | AstNodeUnwrapErrorExpr unwrap_err_expr; |
| 786 | 796 | AstNodePrefixOpExpr prefix_op_expr; |
| ... | ... | @@ -1091,7 +1101,7 @@ enum FnInline { |
| 1091 | 1101 | struct FnTableEntry { |
| 1092 | 1102 | LLVMValueRef llvm_value; |
| 1093 | 1103 | AstNode *proto_node; |
| 1094 | AstNode *fn_def_node; | |
| 1104 | AstNode *body_node; | |
| 1095 | 1105 | ScopeFnDef *fndef_scope; // parent should be the top level decls or container decls |
| 1096 | 1106 | Scope *child_scope; // parent is scope for last parameter |
| 1097 | 1107 | ScopeBlock *def_scope; // parent is child_scope |
| ... | ... | @@ -1161,7 +1171,6 @@ enum BuiltinFnId { |
| 1161 | 1171 | BuiltinFnIdTruncate, |
| 1162 | 1172 | BuiltinFnIdIntType, |
| 1163 | 1173 | BuiltinFnIdUnreachable, |
| 1164 | BuiltinFnIdSetFnTest, | |
| 1165 | 1174 | BuiltinFnIdSetFnVisible, |
| 1166 | 1175 | BuiltinFnIdSetDebugSafety, |
| 1167 | 1176 | BuiltinFnIdAlloca, |
| ... | ... | @@ -1411,8 +1420,8 @@ struct CodeGen { |
| 1411 | 1420 | ZigList<const char *> lib_dirs; |
| 1412 | 1421 | |
| 1413 | 1422 | uint32_t test_fn_count; |
| 1423 | TypeTableEntry *test_fn_type; | |
| 1414 | 1424 | |
| 1415 | bool check_unused; | |
| 1416 | 1425 | bool each_lib_rpath; |
| 1417 | 1426 | |
| 1418 | 1427 | ZigList<AstNode *> error_decls; |
| ... | ... | @@ -1630,7 +1639,6 @@ enum IrInstructionId { |
| 1630 | 1639 | IrInstructionIdTypeOf, |
| 1631 | 1640 | IrInstructionIdToPtrType, |
| 1632 | 1641 | IrInstructionIdPtrTypeChild, |
| 1633 | IrInstructionIdSetFnTest, | |
| 1634 | 1642 | IrInstructionIdSetFnVisible, |
| 1635 | 1643 | IrInstructionIdSetDebugSafety, |
| 1636 | 1644 | IrInstructionIdArrayType, |
| ... | ... | @@ -1973,12 +1981,6 @@ struct IrInstructionPtrTypeChild { |
| 1973 | 1981 | IrInstruction *value; |
| 1974 | 1982 | }; |
| 1975 | 1983 | |
| 1976 | struct IrInstructionSetFnTest { | |
| 1977 | IrInstruction base; | |
| 1978 | ||
| 1979 | IrInstruction *fn_value; | |
| 1980 | }; | |
| 1981 | ||
| 1982 | 1984 | struct IrInstructionSetFnVisible { |
| 1983 | 1985 | IrInstruction base; |
| 1984 | 1986 |
src/analyze.cpp+106-50| ... | ... | @@ -130,7 +130,6 @@ Scope *create_loop_scope(AstNode *node, Scope *parent) { |
| 130 | 130 | } |
| 131 | 131 | |
| 132 | 132 | ScopeFnDef *create_fndef_scope(AstNode *node, Scope *parent, FnTableEntry *fn_entry) { |
| 133 | assert(!node || node->type == NodeTypeFnDef); | |
| 134 | 133 | ScopeFnDef *scope = allocate<ScopeFnDef>(1); |
| 135 | 134 | init_scope(&scope->base, ScopeIdFnDef, node, parent); |
| 136 | 135 | scope->fn_entry = fn_entry; |
| ... | ... | @@ -1756,7 +1755,8 @@ FnTableEntry *create_fn(AstNode *proto_node) { |
| 1756 | 1755 | FnTableEntry *fn_entry = create_fn_raw(inline_value, internal_linkage); |
| 1757 | 1756 | |
| 1758 | 1757 | fn_entry->proto_node = proto_node; |
| 1759 | fn_entry->fn_def_node = proto_node->data.fn_proto.fn_def_node; | |
| 1758 | fn_entry->body_node = (proto_node->data.fn_proto.fn_def_node == nullptr) ? nullptr : | |
| 1759 | proto_node->data.fn_proto.fn_def_node->data.fn_def.body; | |
| 1760 | 1760 | |
| 1761 | 1761 | return fn_entry; |
| 1762 | 1762 | } |
| ... | ... | @@ -1799,76 +1799,107 @@ static void typecheck_panic_fn(CodeGen *g) { |
| 1799 | 1799 | } |
| 1800 | 1800 | } |
| 1801 | 1801 | |
| 1802 | static TypeTableEntry *get_test_fn_type(CodeGen *g) { | |
| 1803 | if (g->test_fn_type) | |
| 1804 | return g->test_fn_type; | |
| 1805 | ||
| 1806 | FnTypeId fn_type_id = {0}; | |
| 1807 | fn_type_id.return_type = g->builtin_types.entry_void; | |
| 1808 | g->test_fn_type = get_fn_type(g, &fn_type_id); | |
| 1809 | return g->test_fn_type; | |
| 1810 | } | |
| 1811 | ||
| 1802 | 1812 | static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| 1803 | 1813 | ImportTableEntry *import = tld_fn->base.import; |
| 1804 | AstNode *proto_node = tld_fn->base.source_node; | |
| 1805 | assert(proto_node->type == NodeTypeFnProto); | |
| 1806 | AstNodeFnProto *fn_proto = &proto_node->data.fn_proto; | |
| 1814 | AstNode *source_node = tld_fn->base.source_node; | |
| 1815 | if (source_node->type == NodeTypeFnProto) { | |
| 1816 | AstNodeFnProto *fn_proto = &source_node->data.fn_proto; | |
| 1807 | 1817 | |
| 1808 | AstNode *fn_def_node = fn_proto->fn_def_node; | |
| 1818 | AstNode *fn_def_node = fn_proto->fn_def_node; | |
| 1809 | 1819 | |
| 1810 | FnTableEntry *fn_table_entry = create_fn(tld_fn->base.source_node); | |
| 1811 | get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_'); | |
| 1820 | FnTableEntry *fn_table_entry = create_fn(source_node); | |
| 1821 | get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_'); | |
| 1812 | 1822 | |
| 1813 | tld_fn->fn_entry = fn_table_entry; | |
| 1823 | tld_fn->fn_entry = fn_table_entry; | |
| 1814 | 1824 | |
| 1815 | if (fn_table_entry->fn_def_node) { | |
| 1816 | fn_table_entry->fndef_scope = create_fndef_scope( | |
| 1817 | fn_table_entry->fn_def_node, tld_fn->base.parent_scope, fn_table_entry); | |
| 1825 | if (fn_table_entry->body_node) { | |
| 1826 | fn_table_entry->fndef_scope = create_fndef_scope( | |
| 1827 | fn_table_entry->body_node, tld_fn->base.parent_scope, fn_table_entry); | |
| 1818 | 1828 | |
| 1819 | for (size_t i = 0; i < fn_proto->params.length; i += 1) { | |
| 1820 | AstNode *param_node = fn_proto->params.at(i); | |
| 1821 | assert(param_node->type == NodeTypeParamDecl); | |
| 1822 | if (buf_len(param_node->data.param_decl.name) == 0) { | |
| 1823 | add_node_error(g, param_node, buf_sprintf("missing parameter name")); | |
| 1829 | for (size_t i = 0; i < fn_proto->params.length; i += 1) { | |
| 1830 | AstNode *param_node = fn_proto->params.at(i); | |
| 1831 | assert(param_node->type == NodeTypeParamDecl); | |
| 1832 | if (buf_len(param_node->data.param_decl.name) == 0) { | |
| 1833 | add_node_error(g, param_node, buf_sprintf("missing parameter name")); | |
| 1834 | } | |
| 1824 | 1835 | } |
| 1825 | 1836 | } |
| 1826 | } | |
| 1827 | 1837 | |
| 1828 | Scope *child_scope = fn_table_entry->fndef_scope ? &fn_table_entry->fndef_scope->base : tld_fn->base.parent_scope; | |
| 1829 | fn_table_entry->type_entry = analyze_fn_type(g, proto_node, child_scope); | |
| 1838 | Scope *child_scope = fn_table_entry->fndef_scope ? &fn_table_entry->fndef_scope->base : tld_fn->base.parent_scope; | |
| 1839 | fn_table_entry->type_entry = analyze_fn_type(g, source_node, child_scope); | |
| 1830 | 1840 | |
| 1831 | if (fn_table_entry->type_entry->id == TypeTableEntryIdInvalid) { | |
| 1832 | tld_fn->base.resolution = TldResolutionInvalid; | |
| 1833 | return; | |
| 1834 | } | |
| 1841 | if (fn_table_entry->type_entry->id == TypeTableEntryIdInvalid) { | |
| 1842 | tld_fn->base.resolution = TldResolutionInvalid; | |
| 1843 | return; | |
| 1844 | } | |
| 1835 | 1845 | |
| 1836 | if (!fn_table_entry->type_entry->data.fn.is_generic) { | |
| 1837 | g->fn_protos.append(fn_table_entry); | |
| 1846 | if (!fn_table_entry->type_entry->data.fn.is_generic) { | |
| 1847 | g->fn_protos.append(fn_table_entry); | |
| 1838 | 1848 | |
| 1839 | if (fn_def_node) | |
| 1840 | g->fn_defs.append(fn_table_entry); | |
| 1849 | if (fn_def_node) | |
| 1850 | g->fn_defs.append(fn_table_entry); | |
| 1841 | 1851 | |
| 1842 | if (import == g->root_import && scope_is_root_decls(tld_fn->base.parent_scope)) { | |
| 1843 | if (buf_eql_str(&fn_table_entry->symbol_name, "main")) { | |
| 1844 | g->main_fn = fn_table_entry; | |
| 1852 | if (import == g->root_import && scope_is_root_decls(tld_fn->base.parent_scope)) { | |
| 1853 | if (buf_eql_str(&fn_table_entry->symbol_name, "main")) { | |
| 1854 | g->main_fn = fn_table_entry; | |
| 1845 | 1855 | |
| 1846 | if (!g->link_libc && tld_fn->base.visib_mod != VisibModExport) { | |
| 1847 | TypeTableEntry *err_void = get_error_type(g, g->builtin_types.entry_void); | |
| 1848 | TypeTableEntry *actual_return_type = fn_table_entry->type_entry->data.fn.fn_type_id.return_type; | |
| 1849 | if (actual_return_type != err_void) { | |
| 1850 | add_node_error(g, fn_proto->return_type, | |
| 1851 | buf_sprintf("expected return type of main to be '%%void', instead is '%s'", | |
| 1852 | buf_ptr(&actual_return_type->name))); | |
| 1856 | if (!g->link_libc && tld_fn->base.visib_mod != VisibModExport) { | |
| 1857 | TypeTableEntry *err_void = get_error_type(g, g->builtin_types.entry_void); | |
| 1858 | TypeTableEntry *actual_return_type = fn_table_entry->type_entry->data.fn.fn_type_id.return_type; | |
| 1859 | if (actual_return_type != err_void) { | |
| 1860 | add_node_error(g, fn_proto->return_type, | |
| 1861 | buf_sprintf("expected return type of main to be '%%void', instead is '%s'", | |
| 1862 | buf_ptr(&actual_return_type->name))); | |
| 1863 | } | |
| 1853 | 1864 | } |
| 1865 | } else if (buf_eql_str(&fn_table_entry->symbol_name, "panic")) { | |
| 1866 | g->panic_fn = fn_table_entry; | |
| 1867 | typecheck_panic_fn(g); | |
| 1868 | } | |
| 1869 | } else if (import->package == g->panic_package && scope_is_root_decls(tld_fn->base.parent_scope)) { | |
| 1870 | if (buf_eql_str(&fn_table_entry->symbol_name, "panic")) { | |
| 1871 | g->panic_fn = fn_table_entry; | |
| 1872 | typecheck_panic_fn(g); | |
| 1854 | 1873 | } |
| 1855 | } else if (buf_eql_str(&fn_table_entry->symbol_name, "panic")) { | |
| 1856 | g->panic_fn = fn_table_entry; | |
| 1857 | typecheck_panic_fn(g); | |
| 1858 | } | |
| 1859 | } else if (import->package == g->panic_package && scope_is_root_decls(tld_fn->base.parent_scope)) { | |
| 1860 | if (buf_eql_str(&fn_table_entry->symbol_name, "panic")) { | |
| 1861 | g->panic_fn = fn_table_entry; | |
| 1862 | typecheck_panic_fn(g); | |
| 1863 | 1874 | } |
| 1864 | 1875 | } |
| 1876 | } else if (source_node->type == NodeTypeTestDecl) { | |
| 1877 | FnTableEntry *fn_table_entry = create_fn_raw(FnInlineAuto, false); | |
| 1878 | ||
| 1879 | get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_'); | |
| 1880 | ||
| 1881 | tld_fn->fn_entry = fn_table_entry; | |
| 1882 | ||
| 1883 | fn_table_entry->proto_node = source_node; | |
| 1884 | fn_table_entry->fndef_scope = create_fndef_scope(source_node, tld_fn->base.parent_scope, fn_table_entry); | |
| 1885 | fn_table_entry->type_entry = get_test_fn_type(g); | |
| 1886 | fn_table_entry->body_node = source_node->data.test_decl.body; | |
| 1887 | fn_table_entry->is_test = true; | |
| 1888 | g->test_fn_count += 1; | |
| 1889 | ||
| 1890 | g->fn_protos.append(fn_table_entry); | |
| 1891 | g->fn_defs.append(fn_table_entry); | |
| 1892 | ||
| 1893 | } else { | |
| 1894 | zig_unreachable(); | |
| 1865 | 1895 | } |
| 1866 | 1896 | } |
| 1867 | 1897 | |
| 1868 | 1898 | static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) { |
| 1869 | if (g->check_unused || g->is_test_build || tld->visib_mod == VisibModExport || | |
| 1899 | if (tld->visib_mod == VisibModExport || | |
| 1870 | 1900 | (buf_eql_str(tld->name, "panic") && |
| 1871 | (decls_scope->import->package == g->panic_package || decls_scope->import == g->root_import))) | |
| 1901 | (decls_scope->import->package == g->panic_package || decls_scope->import == g->root_import)) || | |
| 1902 | (tld->id == TldIdVar && g->is_test_build)) | |
| 1872 | 1903 | { |
| 1873 | 1904 | g->resolve_queue.append(tld); |
| 1874 | 1905 | } |
| ... | ... | @@ -1882,6 +1913,27 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) { |
| 1882 | 1913 | } |
| 1883 | 1914 | } |
| 1884 | 1915 | |
| 1916 | static void preview_test_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) { | |
| 1917 | assert(node->type == NodeTypeTestDecl); | |
| 1918 | ||
| 1919 | if (node->data.test_decl.visib_mod != VisibModPrivate) { | |
| 1920 | add_node_error(g, node, buf_sprintf("tests require no visibility modifier")); | |
| 1921 | } | |
| 1922 | ||
| 1923 | if (!g->is_test_build) | |
| 1924 | return; | |
| 1925 | ||
| 1926 | ImportTableEntry *import = get_scope_import(&decls_scope->base); | |
| 1927 | if (import->package != g->root_package) | |
| 1928 | return; | |
| 1929 | ||
| 1930 | Buf *test_name = node->data.test_decl.name; | |
| 1931 | ||
| 1932 | TldFn *tld_fn = allocate<TldFn>(1); | |
| 1933 | init_tld(&tld_fn->base, TldIdFn, test_name, VisibModPrivate, node, &decls_scope->base); | |
| 1934 | g->resolve_queue.append(&tld_fn->base); | |
| 1935 | } | |
| 1936 | ||
| 1885 | 1937 | static void preview_error_value_decl(CodeGen *g, AstNode *node) { |
| 1886 | 1938 | assert(node->type == NodeTypeErrorValueDecl); |
| 1887 | 1939 | |
| ... | ... | @@ -1975,6 +2027,9 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) { |
| 1975 | 2027 | // error value declarations do not depend on other top level decls |
| 1976 | 2028 | preview_error_value_decl(g, node); |
| 1977 | 2029 | break; |
| 2030 | case NodeTypeTestDecl: | |
| 2031 | preview_test_decl(g, node, decls_scope); | |
| 2032 | break; | |
| 1978 | 2033 | case NodeTypeContainerDecl: |
| 1979 | 2034 | case NodeTypeParamDecl: |
| 1980 | 2035 | case NodeTypeFnDecl: |
| ... | ... | @@ -2650,7 +2705,8 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) { |
| 2650 | 2705 | |
| 2651 | 2706 | fn_table_entry->anal_state = FnAnalStateProbing; |
| 2652 | 2707 | |
| 2653 | AstNode *return_type_node = fn_table_entry->proto_node->data.fn_proto.return_type; | |
| 2708 | AstNode *return_type_node = (fn_table_entry->proto_node != nullptr) ? | |
| 2709 | fn_table_entry->proto_node->data.fn_proto.return_type : fn_table_entry->fndef_scope->base.source_node; | |
| 2654 | 2710 | |
| 2655 | 2711 | assert(fn_table_entry->fndef_scope); |
| 2656 | 2712 | if (!fn_table_entry->child_scope) |
| ... | ... | @@ -2674,7 +2730,7 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) { |
| 2674 | 2730 | } |
| 2675 | 2731 | if (g->verbose) { |
| 2676 | 2732 | fprintf(stderr, "\n"); |
| 2677 | ast_render(stderr, fn_table_entry->fn_def_node, 4); | |
| 2733 | ast_render(stderr, fn_table_entry->body_node, 4); | |
| 2678 | 2734 | fprintf(stderr, "\n{ // (IR)\n"); |
| 2679 | 2735 | ir_print(stderr, &fn_table_entry->ir_executable, 4); |
| 2680 | 2736 | fprintf(stderr, "}\n"); |
src/ast_render.cpp+3| ... | ... | @@ -170,6 +170,8 @@ static const char *node_type_str(NodeType node_type) { |
| 170 | 170 | return "TypeDecl"; |
| 171 | 171 | case NodeTypeErrorValueDecl: |
| 172 | 172 | return "ErrorValueDecl"; |
| 173 | case NodeTypeTestDecl: | |
| 174 | return "TestDecl"; | |
| 173 | 175 | case NodeTypeNumberLiteral: |
| 174 | 176 | return "NumberLiteral"; |
| 175 | 177 | case NodeTypeStringLiteral: |
| ... | ... | @@ -915,6 +917,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { |
| 915 | 917 | case NodeTypeFnDecl: |
| 916 | 918 | case NodeTypeParamDecl: |
| 917 | 919 | case NodeTypeErrorValueDecl: |
| 920 | case NodeTypeTestDecl: | |
| 918 | 921 | case NodeTypeStructField: |
| 919 | 922 | case NodeTypeUse: |
| 920 | 923 | zig_panic("TODO more ast rendering"); |
src/codegen.cpp+1-7| ... | ... | @@ -138,10 +138,6 @@ void codegen_set_verbose(CodeGen *g, bool verbose) { |
| 138 | 138 | g->verbose = verbose; |
| 139 | 139 | } |
| 140 | 140 | |
| 141 | void codegen_set_check_unused(CodeGen *g, bool check_unused) { | |
| 142 | g->check_unused = check_unused; | |
| 143 | } | |
| 144 | ||
| 145 | 141 | void codegen_set_each_lib_rpath(CodeGen *g, bool each_lib_rpath) { |
| 146 | 142 | g->each_lib_rpath = each_lib_rpath; |
| 147 | 143 | } |
| ... | ... | @@ -323,7 +319,7 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) { |
| 323 | 319 | return get_di_scope(g, scope->parent); |
| 324 | 320 | unsigned line_number = fn_table_entry->proto_node->line + 1; |
| 325 | 321 | unsigned scope_line = line_number; |
| 326 | bool is_definition = fn_table_entry->fn_def_node != nullptr; | |
| 322 | bool is_definition = fn_table_entry->body_node != nullptr; | |
| 327 | 323 | unsigned flags = 0; |
| 328 | 324 | bool is_optimized = g->is_release_build; |
| 329 | 325 | ZigLLVMDISubprogram *subprogram = ZigLLVMCreateFunction(g->dbuilder, |
| ... | ... | @@ -2492,7 +2488,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 2492 | 2488 | case IrInstructionIdToPtrType: |
| 2493 | 2489 | case IrInstructionIdPtrTypeChild: |
| 2494 | 2490 | case IrInstructionIdFieldPtr: |
| 2495 | case IrInstructionIdSetFnTest: | |
| 2496 | 2491 | case IrInstructionIdSetFnVisible: |
| 2497 | 2492 | case IrInstructionIdSetDebugSafety: |
| 2498 | 2493 | case IrInstructionIdArrayType: |
| ... | ... | @@ -4054,7 +4049,6 @@ static void define_builtin_fns(CodeGen *g) { |
| 4054 | 4049 | create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX); |
| 4055 | 4050 | create_builtin_fn(g, BuiltinFnIdIntType, "intType", 2); |
| 4056 | 4051 | create_builtin_fn(g, BuiltinFnIdUnreachable, "unreachable", 0); |
| 4057 | create_builtin_fn(g, BuiltinFnIdSetFnTest, "setFnTest", 1); | |
| 4058 | 4052 | create_builtin_fn(g, BuiltinFnIdSetFnVisible, "setFnVisible", 2); |
| 4059 | 4053 | create_builtin_fn(g, BuiltinFnIdSetDebugSafety, "setDebugSafety", 2); |
| 4060 | 4054 | create_builtin_fn(g, BuiltinFnIdAlloca, "alloca", 2); |
src/codegen.hpp-1| ... | ... | @@ -19,7 +19,6 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target); |
| 19 | 19 | void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len); |
| 20 | 20 | void codegen_set_is_release(CodeGen *codegen, bool is_release); |
| 21 | 21 | void codegen_set_is_test(CodeGen *codegen, bool is_test); |
| 22 | void codegen_set_check_unused(CodeGen *codegen, bool check_unused); | |
| 23 | 22 | void codegen_set_each_lib_rpath(CodeGen *codegen, bool each_lib_rpath); |
| 24 | 23 | |
| 25 | 24 | void codegen_set_is_static(CodeGen *codegen, bool is_static); |
src/ir.cpp+5-60| ... | ... | @@ -282,10 +282,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrTypeChild *) |
| 282 | 282 | return IrInstructionIdPtrTypeChild; |
| 283 | 283 | } |
| 284 | 284 | |
| 285 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSetFnTest *) { | |
| 286 | return IrInstructionIdSetFnTest; | |
| 287 | } | |
| 288 | ||
| 289 | 285 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSetFnVisible *) { |
| 290 | 286 | return IrInstructionIdSetFnVisible; |
| 291 | 287 | } |
| ... | ... | @@ -1147,17 +1143,6 @@ static IrInstruction *ir_build_ptr_type_child(IrBuilder *irb, Scope *scope, AstN |
| 1147 | 1143 | return &instruction->base; |
| 1148 | 1144 | } |
| 1149 | 1145 | |
| 1150 | static IrInstruction *ir_build_set_fn_test(IrBuilder *irb, Scope *scope, AstNode *source_node, | |
| 1151 | IrInstruction *fn_value) | |
| 1152 | { | |
| 1153 | IrInstructionSetFnTest *instruction = ir_build_instruction<IrInstructionSetFnTest>(irb, scope, source_node); | |
| 1154 | instruction->fn_value = fn_value; | |
| 1155 | ||
| 1156 | ir_ref_instruction(fn_value, irb->current_basic_block); | |
| 1157 | ||
| 1158 | return &instruction->base; | |
| 1159 | } | |
| 1160 | ||
| 1161 | 1146 | static IrInstruction *ir_build_set_fn_visible(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *fn_value, |
| 1162 | 1147 | IrInstruction *is_visible) |
| 1163 | 1148 | { |
| ... | ... | @@ -2287,13 +2272,6 @@ static IrInstruction *ir_instruction_ptrtypechild_get_dep(IrInstructionPtrTypeCh |
| 2287 | 2272 | } |
| 2288 | 2273 | } |
| 2289 | 2274 | |
| 2290 | static IrInstruction *ir_instruction_setfntest_get_dep(IrInstructionSetFnTest *instruction, size_t index) { | |
| 2291 | switch (index) { | |
| 2292 | case 0: return instruction->fn_value; | |
| 2293 | default: return nullptr; | |
| 2294 | } | |
| 2295 | } | |
| 2296 | ||
| 2297 | 2275 | static IrInstruction *ir_instruction_setfnvisible_get_dep(IrInstructionSetFnVisible *instruction, size_t index) { |
| 2298 | 2276 | switch (index) { |
| 2299 | 2277 | case 0: return instruction->fn_value; |
| ... | ... | @@ -2807,8 +2785,6 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t |
| 2807 | 2785 | return ir_instruction_toptrtype_get_dep((IrInstructionToPtrType *) instruction, index); |
| 2808 | 2786 | case IrInstructionIdPtrTypeChild: |
| 2809 | 2787 | return ir_instruction_ptrtypechild_get_dep((IrInstructionPtrTypeChild *) instruction, index); |
| 2810 | case IrInstructionIdSetFnTest: | |
| 2811 | return ir_instruction_setfntest_get_dep((IrInstructionSetFnTest *) instruction, index); | |
| 2812 | 2788 | case IrInstructionIdSetFnVisible: |
| 2813 | 2789 | return ir_instruction_setfnvisible_get_dep((IrInstructionSetFnVisible *) instruction, index); |
| 2814 | 2790 | case IrInstructionIdSetDebugSafety: |
| ... | ... | @@ -3810,15 +3786,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 3810 | 3786 | return arg; |
| 3811 | 3787 | return ir_build_typeof(irb, scope, node, arg); |
| 3812 | 3788 | } |
| 3813 | case BuiltinFnIdSetFnTest: | |
| 3814 | { | |
| 3815 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | |
| 3816 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); | |
| 3817 | if (arg0_value == irb->codegen->invalid_instruction) | |
| 3818 | return arg0_value; | |
| 3819 | ||
| 3820 | return ir_build_set_fn_test(irb, scope, node, arg0_value); | |
| 3821 | } | |
| 3822 | 3789 | case BuiltinFnIdSetFnVisible: |
| 3823 | 3790 | { |
| 3824 | 3791 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| ... | ... | @@ -5543,6 +5510,8 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 5543 | 5510 | zig_panic("TODO IR gen NodeTypeErrorValueDecl"); |
| 5544 | 5511 | case NodeTypeTypeDecl: |
| 5545 | 5512 | zig_panic("TODO IR gen NodeTypeTypeDecl"); |
| 5513 | case NodeTypeTestDecl: | |
| 5514 | zig_panic("TODO IR gen NodeTypeTestDecl"); | |
| 5546 | 5515 | } |
| 5547 | 5516 | zig_unreachable(); |
| 5548 | 5517 | } |
| ... | ... | @@ -5633,10 +5602,7 @@ bool ir_gen_fn(CodeGen *codegen, FnTableEntry *fn_entry) { |
| 5633 | 5602 | assert(fn_entry); |
| 5634 | 5603 | |
| 5635 | 5604 | IrExecutable *ir_executable = &fn_entry->ir_executable; |
| 5636 | AstNode *fn_def_node = fn_entry->fn_def_node; | |
| 5637 | assert(fn_def_node->type == NodeTypeFnDef); | |
| 5638 | ||
| 5639 | AstNode *body_node = fn_def_node->data.fn_def.body; | |
| 5605 | AstNode *body_node = fn_entry->body_node; | |
| 5640 | 5606 | |
| 5641 | 5607 | assert(fn_entry->child_scope); |
| 5642 | 5608 | |
| ... | ... | @@ -8180,7 +8146,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 8180 | 8146 | result = entry->value; |
| 8181 | 8147 | } else { |
| 8182 | 8148 | // Analyze the fn body block like any other constant expression. |
| 8183 | AstNode *body_node = fn_entry->fn_def_node->data.fn_def.body; | |
| 8149 | AstNode *body_node = fn_entry->body_node; | |
| 8184 | 8150 | result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type, |
| 8185 | 8151 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry, |
| 8186 | 8152 | nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec); |
| ... | ... | @@ -8219,7 +8185,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 8219 | 8185 | FnTableEntry *impl_fn = create_fn(fn_proto_node); |
| 8220 | 8186 | impl_fn->param_source_nodes = allocate<AstNode *>(new_fn_arg_count); |
| 8221 | 8187 | buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name); |
| 8222 | impl_fn->fndef_scope = create_fndef_scope(impl_fn->fn_def_node, parent_scope, impl_fn); | |
| 8188 | impl_fn->fndef_scope = create_fndef_scope(impl_fn->body_node, parent_scope, impl_fn); | |
| 8223 | 8189 | impl_fn->child_scope = &impl_fn->fndef_scope->base; |
| 8224 | 8190 | FnTypeId inst_fn_type_id = {0}; |
| 8225 | 8191 | init_fn_type_id(&inst_fn_type_id, fn_proto_node, new_fn_arg_count); |
| ... | ... | @@ -9582,24 +9548,6 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type_child(IrAnalyze *ira, |
| 9582 | 9548 | return ira->codegen->builtin_types.entry_type; |
| 9583 | 9549 | } |
| 9584 | 9550 | |
| 9585 | static TypeTableEntry *ir_analyze_instruction_set_fn_test(IrAnalyze *ira, | |
| 9586 | IrInstructionSetFnTest *set_fn_test_instruction) | |
| 9587 | { | |
| 9588 | IrInstruction *fn_value = set_fn_test_instruction->fn_value->other; | |
| 9589 | ||
| 9590 | FnTableEntry *fn_entry = ir_resolve_fn(ira, fn_value); | |
| 9591 | if (!fn_entry) | |
| 9592 | return ira->codegen->builtin_types.entry_invalid; | |
| 9593 | ||
| 9594 | if (!fn_entry->is_test) { | |
| 9595 | fn_entry->is_test = true; | |
| 9596 | ira->codegen->test_fn_count += 1; | |
| 9597 | } | |
| 9598 | ||
| 9599 | ir_build_const_from(ira, &set_fn_test_instruction->base); | |
| 9600 | return ira->codegen->builtin_types.entry_void; | |
| 9601 | } | |
| 9602 | ||
| 9603 | 9551 | static TypeTableEntry *ir_analyze_instruction_set_fn_visible(IrAnalyze *ira, |
| 9604 | 9552 | IrInstructionSetFnVisible *set_fn_visible_instruction) |
| 9605 | 9553 | { |
| ... | ... | @@ -12253,8 +12201,6 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 12253 | 12201 | return ir_analyze_instruction_to_ptr_type(ira, (IrInstructionToPtrType *)instruction); |
| 12254 | 12202 | case IrInstructionIdPtrTypeChild: |
| 12255 | 12203 | return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction); |
| 12256 | case IrInstructionIdSetFnTest: | |
| 12257 | return ir_analyze_instruction_set_fn_test(ira, (IrInstructionSetFnTest *)instruction); | |
| 12258 | 12204 | case IrInstructionIdSetFnVisible: |
| 12259 | 12205 | return ir_analyze_instruction_set_fn_visible(ira, (IrInstructionSetFnVisible *)instruction); |
| 12260 | 12206 | case IrInstructionIdSetGlobalAlign: |
| ... | ... | @@ -12469,7 +12415,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 12469 | 12415 | case IrInstructionIdCall: |
| 12470 | 12416 | case IrInstructionIdReturn: |
| 12471 | 12417 | case IrInstructionIdUnreachable: |
| 12472 | case IrInstructionIdSetFnTest: | |
| 12473 | 12418 | case IrInstructionIdSetFnVisible: |
| 12474 | 12419 | case IrInstructionIdSetDebugSafety: |
| 12475 | 12420 | case IrInstructionIdImport: |
src/ir_print.cpp-9| ... | ... | @@ -339,12 +339,6 @@ static void ir_print_enum_field_ptr(IrPrint *irp, IrInstructionEnumFieldPtr *ins |
| 339 | 339 | fprintf(irp->f, ")"); |
| 340 | 340 | } |
| 341 | 341 | |
| 342 | static void ir_print_set_fn_test(IrPrint *irp, IrInstructionSetFnTest *instruction) { | |
| 343 | fprintf(irp->f, "@setFnTest("); | |
| 344 | ir_print_other_instruction(irp, instruction->fn_value); | |
| 345 | fprintf(irp->f, ")"); | |
| 346 | } | |
| 347 | ||
| 348 | 342 | static void ir_print_set_fn_visible(IrPrint *irp, IrInstructionSetFnVisible *instruction) { |
| 349 | 343 | fprintf(irp->f, "@setFnVisible("); |
| 350 | 344 | ir_print_other_instruction(irp, instruction->fn_value); |
| ... | ... | @@ -932,9 +926,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 932 | 926 | case IrInstructionIdEnumFieldPtr: |
| 933 | 927 | ir_print_enum_field_ptr(irp, (IrInstructionEnumFieldPtr *)instruction); |
| 934 | 928 | break; |
| 935 | case IrInstructionIdSetFnTest: | |
| 936 | ir_print_set_fn_test(irp, (IrInstructionSetFnTest *)instruction); | |
| 937 | break; | |
| 938 | 929 | case IrInstructionIdSetFnVisible: |
| 939 | 930 | ir_print_set_fn_visible(irp, (IrInstructionSetFnVisible *)instruction); |
| 940 | 931 | break; |
src/main.cpp-5| ... | ... | @@ -56,7 +56,6 @@ static int usage(const char *arg0) { |
| 56 | 56 | " -mmacosx-version-min [ver] (darwin only) set Mac OS X deployment target\n" |
| 57 | 57 | " -mios-version-min [ver] (darwin only) set iOS deployment target\n" |
| 58 | 58 | " -framework [name] (darwin only) link against framework\n" |
| 59 | " --check-unused perform semantic analysis on unused declarations\n" | |
| 60 | 59 | " --linker-script [path] use a custom linker script\n" |
| 61 | 60 | " -rpath [path] add directory to the runtime library search path\n" |
| 62 | 61 | " --each-lib-rpath add rpath for each used dynamic library\n" |
| ... | ... | @@ -141,7 +140,6 @@ int main(int argc, char **argv) { |
| 141 | 140 | bool rdynamic = false; |
| 142 | 141 | const char *mmacosx_version_min = nullptr; |
| 143 | 142 | const char *mios_version_min = nullptr; |
| 144 | bool check_unused = false; | |
| 145 | 143 | const char *linker_script = nullptr; |
| 146 | 144 | ZigList<const char *> rpath_list = {0}; |
| 147 | 145 | bool each_lib_rpath = false; |
| ... | ... | @@ -166,8 +164,6 @@ int main(int argc, char **argv) { |
| 166 | 164 | municode = true; |
| 167 | 165 | } else if (strcmp(arg, "-rdynamic") == 0) { |
| 168 | 166 | rdynamic = true; |
| 169 | } else if (strcmp(arg, "--check-unused") == 0) { | |
| 170 | check_unused = true; | |
| 171 | 167 | } else if (strcmp(arg, "--each-lib-rpath") == 0) { |
| 172 | 168 | each_lib_rpath = true; |
| 173 | 169 | } else if (arg[1] == 'L' && arg[2] != 0) { |
| ... | ... | @@ -354,7 +350,6 @@ int main(int argc, char **argv) { |
| 354 | 350 | codegen_set_is_release(g, is_release_build); |
| 355 | 351 | codegen_set_is_test(g, cmd == CmdTest); |
| 356 | 352 | codegen_set_linker_script(g, linker_script); |
| 357 | codegen_set_check_unused(g, check_unused); | |
| 358 | 353 | if (each_lib_rpath) |
| 359 | 354 | codegen_set_each_lib_rpath(g, each_lib_rpath); |
| 360 | 355 |
src/parser.cpp+31-1| ... | ... | @@ -2417,6 +2417,27 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, size_t *token_index |
| 2417 | 2417 | return node; |
| 2418 | 2418 | } |
| 2419 | 2419 | |
| 2420 | /* | |
| 2421 | TestDecl = "test" String Block | |
| 2422 | */ | |
| 2423 | static AstNode *ast_parse_test_decl_node(ParseContext *pc, size_t *token_index, VisibMod visib_mod) { | |
| 2424 | Token *first_token = &pc->tokens->at(*token_index); | |
| 2425 | ||
| 2426 | if (first_token->id != TokenIdKeywordTest) { | |
| 2427 | return nullptr; | |
| 2428 | } | |
| 2429 | *token_index += 1; | |
| 2430 | ||
| 2431 | Token *name_tok = ast_eat_token(pc, token_index, TokenIdStringLiteral); | |
| 2432 | ||
| 2433 | AstNode *node = ast_create_node(pc, NodeTypeTestDecl, first_token); | |
| 2434 | node->data.test_decl.visib_mod = visib_mod; | |
| 2435 | node->data.test_decl.name = token_buf(name_tok); | |
| 2436 | node->data.test_decl.body = ast_parse_block(pc, token_index, true); | |
| 2437 | ||
| 2438 | return node; | |
| 2439 | } | |
| 2440 | ||
| 2420 | 2441 | /* |
| 2421 | 2442 | TypeDecl = "type" "Symbol" "=" TypeExpr ";" |
| 2422 | 2443 | */ |
| ... | ... | @@ -2443,7 +2464,7 @@ static AstNode *ast_parse_type_decl(ParseContext *pc, size_t *token_index, Visib |
| 2443 | 2464 | } |
| 2444 | 2465 | |
| 2445 | 2466 | /* |
| 2446 | TopLevelItem = ErrorValueDecl | Block | TopLevelDecl | |
| 2467 | TopLevelItem = ErrorValueDecl | Block | TopLevelDecl | TestDecl | |
| 2447 | 2468 | TopLevelDecl = option(VisibleMod) (FnDef | ExternDecl | GlobalVarDecl | TypeDecl | UseDecl) |
| 2448 | 2469 | */ |
| 2449 | 2470 | static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, ZigList<AstNode *> *top_level_decls) { |
| ... | ... | @@ -2491,6 +2512,12 @@ static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, Zig |
| 2491 | 2512 | continue; |
| 2492 | 2513 | } |
| 2493 | 2514 | |
| 2515 | AstNode *test_decl_node = ast_parse_test_decl_node(pc, token_index, visib_mod); | |
| 2516 | if (test_decl_node) { | |
| 2517 | top_level_decls->append(test_decl_node); | |
| 2518 | continue; | |
| 2519 | } | |
| 2520 | ||
| 2494 | 2521 | AstNode *type_decl_node = ast_parse_type_decl(pc, token_index, visib_mod); |
| 2495 | 2522 | if (type_decl_node) { |
| 2496 | 2523 | top_level_decls->append(type_decl_node); |
| ... | ... | @@ -2585,6 +2612,9 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont |
| 2585 | 2612 | case NodeTypeErrorValueDecl: |
| 2586 | 2613 | // none |
| 2587 | 2614 | break; |
| 2615 | case NodeTypeTestDecl: | |
| 2616 | visit_field(&node->data.test_decl.body, visit, context); | |
| 2617 | break; | |
| 2588 | 2618 | case NodeTypeBinOpExpr: |
| 2589 | 2619 | visit_field(&node->data.bin_op_expr.op1, visit, context); |
| 2590 | 2620 | visit_field(&node->data.bin_op_expr.op2, visit, context); |
src/tokenizer.cpp+2| ... | ... | @@ -133,6 +133,7 @@ static const struct ZigKeyword zig_keywords[] = { |
| 133 | 133 | {"return", TokenIdKeywordReturn}, |
| 134 | 134 | {"struct", TokenIdKeywordStruct}, |
| 135 | 135 | {"switch", TokenIdKeywordSwitch}, |
| 136 | {"test", TokenIdKeywordTest}, | |
| 136 | 137 | {"this", TokenIdKeywordThis}, |
| 137 | 138 | {"true", TokenIdKeywordTrue}, |
| 138 | 139 | {"try", TokenIdKeywordTry}, |
| ... | ... | @@ -1508,6 +1509,7 @@ const char * token_name(TokenId id) { |
| 1508 | 1509 | case TokenIdKeywordReturn: return "return"; |
| 1509 | 1510 | case TokenIdKeywordStruct: return "struct"; |
| 1510 | 1511 | case TokenIdKeywordSwitch: return "switch"; |
| 1512 | case TokenIdKeywordTest: return "test"; | |
| 1511 | 1513 | case TokenIdKeywordThis: return "this"; |
| 1512 | 1514 | case TokenIdKeywordTrue: return "true"; |
| 1513 | 1515 | case TokenIdKeywordTry: return "try"; |
src/tokenizer.hpp+1| ... | ... | @@ -74,6 +74,7 @@ enum TokenId { |
| 74 | 74 | TokenIdKeywordReturn, |
| 75 | 75 | TokenIdKeywordStruct, |
| 76 | 76 | TokenIdKeywordSwitch, |
| 77 | TokenIdKeywordTest, | |
| 77 | 78 | TokenIdKeywordThis, |
| 78 | 79 | TokenIdKeywordTrue, |
| 79 | 80 | TokenIdKeywordTry, |
std/compiler_rt.zig+3-9| ... | ... | @@ -322,9 +322,7 @@ export fn __udivsi3(n: su_int, d: su_int) -> su_int { |
| 322 | 322 | return q; |
| 323 | 323 | } |
| 324 | 324 | |
| 325 | fn test_umoddi3() { | |
| 326 | @setFnTest(this); | |
| 327 | ||
| 325 | test "test_umoddi3" { | |
| 328 | 326 | test_one_umoddi3(0, 1, 0); |
| 329 | 327 | test_one_umoddi3(2, 1, 0); |
| 330 | 328 | test_one_umoddi3(0x8000000000000000, 1, 0x0); |
| ... | ... | @@ -337,9 +335,7 @@ fn test_one_umoddi3(a: du_int, b: du_int, expected_r: du_int) { |
| 337 | 335 | assert(r == expected_r); |
| 338 | 336 | } |
| 339 | 337 | |
| 340 | fn test_udivmoddi4() { | |
| 341 | @setFnTest(this); | |
| 342 | ||
| 338 | test "test_udivmoddi4" { | |
| 343 | 339 | const cases = [][4]du_int { |
| 344 | 340 | []du_int{0x0000000000000000, 0x0000000000000001, 0x0000000000000000, 0x0000000000000000}, |
| 345 | 341 | []du_int{0x0000000080000000, 0x0000000100000001, 0x0000000000000000, 0x0000000080000000}, |
| ... | ... | @@ -367,9 +363,7 @@ fn test_one_udivmoddi4(a: du_int, b: du_int, expected_q: du_int, expected_r: du_ |
| 367 | 363 | assert(r == expected_r); |
| 368 | 364 | } |
| 369 | 365 | |
| 370 | fn test_udivsi3() { | |
| 371 | @setFnTest(this); | |
| 372 | ||
| 366 | test "test_udivsi3" { | |
| 373 | 367 | const cases = [][3]su_int { |
| 374 | 368 | []su_int{0x00000000, 0x00000001, 0x00000000}, |
| 375 | 369 | []su_int{0x00000000, 0x00000002, 0x00000000}, |
std/cstr.zig+2-6| ... | ... | @@ -140,9 +140,7 @@ pub const Buffer0 = struct { |
| 140 | 140 | } |
| 141 | 141 | }; |
| 142 | 142 | |
| 143 | fn testSimpleBuffer0() { | |
| 144 | @setFnTest(this); | |
| 145 | ||
| 143 | test "simple Buffer0" { | |
| 146 | 144 | var buf = %%Buffer0.initEmpty(&debug.global_allocator); |
| 147 | 145 | assert(buf.len() == 0); |
| 148 | 146 | %%buf.appendCStr(c"hello"); |
| ... | ... | @@ -162,9 +160,7 @@ fn testSimpleBuffer0() { |
| 162 | 160 | assert(buf.startsWithOther(&buf2)); |
| 163 | 161 | } |
| 164 | 162 | |
| 165 | fn testCStrFns() { | |
| 166 | @setFnTest(this); | |
| 167 | ||
| 163 | test "cstr fns" { | |
| 168 | 164 | comptime testCStrFnsImpl(); |
| 169 | 165 | testCStrFnsImpl(); |
| 170 | 166 | } |
std/fmt.zig+3-9| ... | ... | @@ -291,9 +291,7 @@ fn digitToChar(digit: u8, uppercase: bool) -> u8 { |
| 291 | 291 | }; |
| 292 | 292 | } |
| 293 | 293 | |
| 294 | fn testBufPrintInt() { | |
| 295 | @setFnTest(this); | |
| 296 | ||
| 294 | test "testBufPrintInt" { | |
| 297 | 295 | var buffer: [max_int_digits]u8 = undefined; |
| 298 | 296 | const buf = buffer[0...]; |
| 299 | 297 | assert(mem.eql(u8, bufPrintIntToSlice(buf, i32(-12345678), 2, false, 0), "-101111000110000101001110")); |
| ... | ... | @@ -315,9 +313,7 @@ fn bufPrintIntToSlice(buf: []u8, value: var, base: u8, uppercase: bool, width: u |
| 315 | 313 | return buf[0...formatIntBuf(buf, value, base, uppercase, width)]; |
| 316 | 314 | } |
| 317 | 315 | |
| 318 | fn testParseU64DigitTooBig() { | |
| 319 | @setFnTest(this); | |
| 320 | ||
| 316 | test "testParseU64DigitTooBig" { | |
| 321 | 317 | parseUnsigned(u64, "123a", 10) %% |err| { |
| 322 | 318 | if (err == error.InvalidChar) return; |
| 323 | 319 | @unreachable(); |
| ... | ... | @@ -325,9 +321,7 @@ fn testParseU64DigitTooBig() { |
| 325 | 321 | @unreachable(); |
| 326 | 322 | } |
| 327 | 323 | |
| 328 | fn testParseUnsignedComptime() { | |
| 329 | @setFnTest(this); | |
| 330 | ||
| 324 | test "testParseUnsignedComptime" { | |
| 331 | 325 | comptime { |
| 332 | 326 | assert(%%parseUnsigned(usize, "2", 10) == 2); |
| 333 | 327 | } |
std/hash_map.zig+1-3| ... | ... | @@ -219,9 +219,7 @@ pub fn HashMap(comptime K: type, comptime V: type, |
| 219 | 219 | } |
| 220 | 220 | } |
| 221 | 221 | |
| 222 | fn basicHashMapTest() { | |
| 223 | @setFnTest(this); | |
| 224 | ||
| 222 | test "basicHashMapTest" { | |
| 225 | 223 | var map: HashMap(i32, i32, hash_i32, eql_i32) = undefined; |
| 226 | 224 | map.init(&debug.global_allocator); |
| 227 | 225 | defer map.deinit(); |
std/list.zig+1-3| ... | ... | @@ -64,9 +64,7 @@ pub fn List(comptime T: type) -> type{ |
| 64 | 64 | } |
| 65 | 65 | } |
| 66 | 66 | |
| 67 | fn basicListTest() { | |
| 68 | @setFnTest(this); | |
| 69 | ||
| 67 | test "basicListTest" { | |
| 70 | 68 | var list = List(i32).init(&debug.global_allocator); |
| 71 | 69 | defer list.deinit(); |
| 72 | 70 |
std/math.zig+1-3| ... | ... | @@ -68,9 +68,7 @@ fn getReturnTypeForAbs(comptime T: type) -> type { |
| 68 | 68 | } |
| 69 | 69 | } |
| 70 | 70 | |
| 71 | fn testMath() { | |
| 72 | @setFnTest(this); | |
| 73 | ||
| 71 | test "testMath" { | |
| 74 | 72 | testMathImpl(); |
| 75 | 73 | comptime testMathImpl(); |
| 76 | 74 | } |
std/mem.zig+3-9| ... | ... | @@ -117,17 +117,13 @@ pub fn writeInt(buf: []u8, value: var, big_endian: bool) { |
| 117 | 117 | assert(bits == 0); |
| 118 | 118 | } |
| 119 | 119 | |
| 120 | fn testStringEquality() { | |
| 121 | @setFnTest(this); | |
| 122 | ||
| 120 | test "testStringEquality" { | |
| 123 | 121 | assert(eql(u8, "abcd", "abcd")); |
| 124 | 122 | assert(!eql(u8, "abcdef", "abZdef")); |
| 125 | 123 | assert(!eql(u8, "abcdefg", "abcdef")); |
| 126 | 124 | } |
| 127 | 125 | |
| 128 | fn testReadInt() { | |
| 129 | @setFnTest(this); | |
| 130 | ||
| 126 | test "testReadInt" { | |
| 131 | 127 | testReadIntImpl(); |
| 132 | 128 | comptime testReadIntImpl(); |
| 133 | 129 | } |
| ... | ... | @@ -149,9 +145,7 @@ fn testReadIntImpl() { |
| 149 | 145 | } |
| 150 | 146 | } |
| 151 | 147 | |
| 152 | fn testWriteInt() { | |
| 153 | @setFnTest(this); | |
| 154 | ||
| 148 | test "testWriteInt" { | |
| 155 | 149 | testWriteIntImpl(); |
| 156 | 150 | comptime testWriteIntImpl(); |
| 157 | 151 | } |
std/rand.zig+3-9| ... | ... | @@ -158,9 +158,7 @@ fn MersenneTwister( |
| 158 | 158 | } |
| 159 | 159 | } |
| 160 | 160 | |
| 161 | fn testFloat32() { | |
| 162 | @setFnTest(this); | |
| 163 | ||
| 161 | test "testFloat32" { | |
| 164 | 162 | var r: Rand = undefined; |
| 165 | 163 | r.init(42); |
| 166 | 164 | |
| ... | ... | @@ -171,9 +169,7 @@ fn testFloat32() { |
| 171 | 169 | }} |
| 172 | 170 | } |
| 173 | 171 | |
| 174 | fn testMT19937_64() { | |
| 175 | @setFnTest(this); | |
| 176 | ||
| 172 | test "testMT19937_64" { | |
| 177 | 173 | var rng: MT19937_64 = undefined; |
| 178 | 174 | rng.init(rand_test.mt64_seed); |
| 179 | 175 | for (rand_test.mt64_data) |value| { |
| ... | ... | @@ -181,9 +177,7 @@ fn testMT19937_64() { |
| 181 | 177 | } |
| 182 | 178 | } |
| 183 | 179 | |
| 184 | fn testMT19937_32() { | |
| 185 | @setFnTest(this); | |
| 186 | ||
| 180 | test "testMT19937_32" { | |
| 187 | 181 | var rng: MT19937_32 = undefined; |
| 188 | 182 | rng.init(rand_test.mt32_seed); |
| 189 | 183 | for (rand_test.mt32_data) |value| { |
std/sort.zig+2-6| ... | ... | @@ -58,9 +58,7 @@ fn reverse(was: Cmp) -> Cmp { |
| 58 | 58 | // --------------------------------------- |
| 59 | 59 | // tests |
| 60 | 60 | |
| 61 | fn testSort() { | |
| 62 | @setFnTest(this); | |
| 63 | ||
| 61 | test "testSort" { | |
| 64 | 62 | const u8cases = [][]const []const u8 { |
| 65 | 63 | [][]const u8{"", ""}, |
| 66 | 64 | [][]const u8{"a", "a"}, |
| ... | ... | @@ -96,9 +94,7 @@ fn testSort() { |
| 96 | 94 | } |
| 97 | 95 | } |
| 98 | 96 | |
| 99 | fn testSortDesc() { | |
| 100 | @setFnTest(this); | |
| 101 | ||
| 97 | test "testSortDesc" { | |
| 102 | 98 | const rev_cases = [][]const []const i32 { |
| 103 | 99 | [][]const i32{[]i32{}, []i32{}}, |
| 104 | 100 | [][]const i32{[]i32{1}, []i32{1}}, |
test/cases/array.zig+6-18| ... | ... | @@ -1,9 +1,7 @@ |
| 1 | 1 | const assert = @import("std").debug.assert; |
| 2 | 2 | const mem = @import("std").mem; |
| 3 | 3 | |
| 4 | fn arrays() { | |
| 5 | @setFnTest(this); | |
| 6 | ||
| 4 | test "arrays" { | |
| 7 | 5 | var array : [5]u32 = undefined; |
| 8 | 6 | |
| 9 | 7 | var i : u32 = 0; |
| ... | ... | @@ -27,9 +25,7 @@ fn getArrayLen(a: []const u32) -> usize { |
| 27 | 25 | a.len |
| 28 | 26 | } |
| 29 | 27 | |
| 30 | fn voidArrays() { | |
| 31 | @setFnTest(this); | |
| 32 | ||
| 28 | test "voidArrays" { | |
| 33 | 29 | var array: [4]void = undefined; |
| 34 | 30 | array[0] = void{}; |
| 35 | 31 | array[1] = array[2]; |
| ... | ... | @@ -37,18 +33,14 @@ fn voidArrays() { |
| 37 | 33 | assert(array.len == 4); |
| 38 | 34 | } |
| 39 | 35 | |
| 40 | fn arrayLiteral() { | |
| 41 | @setFnTest(this); | |
| 42 | ||
| 36 | test "arrayLiteral" { | |
| 43 | 37 | const hex_mult = []u16{4096, 256, 16, 1}; |
| 44 | 38 | |
| 45 | 39 | assert(hex_mult.len == 4); |
| 46 | 40 | assert(hex_mult[1] == 256); |
| 47 | 41 | } |
| 48 | 42 | |
| 49 | fn arrayDotLenConstExpr() { | |
| 50 | @setFnTest(this); | |
| 51 | ||
| 43 | test "arrayDotLenConstExpr" { | |
| 52 | 44 | assert(comptime {some_array.len == 4}); |
| 53 | 45 | } |
| 54 | 46 | |
| ... | ... | @@ -58,9 +50,7 @@ const ArrayDotLenConstExpr = struct { |
| 58 | 50 | const some_array = []u8 {0, 1, 2, 3}; |
| 59 | 51 | |
| 60 | 52 | |
| 61 | fn nestedArrays() { | |
| 62 | @setFnTest(this); | |
| 63 | ||
| 53 | test "nestedArrays" { | |
| 64 | 54 | const array_of_strings = [][]const u8 {"hello", "this", "is", "my", "thing"}; |
| 65 | 55 | for (array_of_strings) |s, i| { |
| 66 | 56 | if (i == 0) assert(mem.eql(u8, s, "hello")); |
| ... | ... | @@ -79,9 +69,7 @@ const Sub = struct { |
| 79 | 69 | const Str = struct { |
| 80 | 70 | a: []Sub, |
| 81 | 71 | }; |
| 82 | fn setGlobalVarArrayViaSliceEmbeddedInStruct() { | |
| 83 | @setFnTest(this); | |
| 84 | ||
| 72 | test "setGlobalVarArrayViaSliceEmbeddedInStruct" { | |
| 85 | 73 | var s = Str { .a = s_array[0...]}; |
| 86 | 74 | |
| 87 | 75 | s.a[0].b = 1; |
test/cases/atomics.zig+2-6| ... | ... | @@ -1,16 +1,12 @@ |
| 1 | 1 | const assert = @import("std").debug.assert; |
| 2 | 2 | |
| 3 | fn cmpxchg() { | |
| 4 | @setFnTest(this); | |
| 5 | ||
| 3 | test "cmpxchg" { | |
| 6 | 4 | var x: i32 = 1234; |
| 7 | 5 | while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) {} |
| 8 | 6 | assert(x == 5678); |
| 9 | 7 | } |
| 10 | 8 | |
| 11 | fn fence() { | |
| 12 | @setFnTest(this); | |
| 13 | ||
| 9 | test "fence" { | |
| 14 | 10 | var x: i32 = 1234; |
| 15 | 11 | @fence(AtomicOrder.SeqCst); |
| 16 | 12 | x = 5678; |
test/cases/bool.zig+5-15| ... | ... | @@ -1,15 +1,11 @@ |
| 1 | 1 | const assert = @import("std").debug.assert; |
| 2 | 2 | |
| 3 | fn boolLiterals() { | |
| 4 | @setFnTest(this); | |
| 5 | ||
| 3 | test "boolLiterals" { | |
| 6 | 4 | assert(true); |
| 7 | 5 | assert(!false); |
| 8 | 6 | } |
| 9 | 7 | |
| 10 | fn castBoolToInt() { | |
| 11 | @setFnTest(this); | |
| 12 | ||
| 8 | test "castBoolToInt" { | |
| 13 | 9 | const t = true; |
| 14 | 10 | const f = false; |
| 15 | 11 | assert(i32(t) == i32(1)); |
| ... | ... | @@ -22,18 +18,14 @@ fn nonConstCastBoolToInt(t: bool, f: bool) { |
| 22 | 18 | assert(i32(f) == i32(0)); |
| 23 | 19 | } |
| 24 | 20 | |
| 25 | fn boolCmp() { | |
| 26 | @setFnTest(this); | |
| 27 | ||
| 21 | test "boolCmp" { | |
| 28 | 22 | assert(testBoolCmp(true, false) == false); |
| 29 | 23 | } |
| 30 | 24 | fn testBoolCmp(a: bool, b: bool) -> bool { |
| 31 | 25 | a == b |
| 32 | 26 | } |
| 33 | 27 | |
| 34 | fn shortCircuitAndOr() { | |
| 35 | @setFnTest(this); | |
| 36 | ||
| 28 | test "shortCircuitAndOr" { | |
| 37 | 29 | var a = true; |
| 38 | 30 | a &&= false; |
| 39 | 31 | assert(!a); |
| ... | ... | @@ -49,9 +41,7 @@ const global_f = false; |
| 49 | 41 | const global_t = true; |
| 50 | 42 | const not_global_f = !global_f; |
| 51 | 43 | const not_global_t = !global_t; |
| 52 | fn compileTimeBoolnot() { | |
| 53 | @setFnTest(this); | |
| 54 | ||
| 44 | test "compileTimeBoolnot" { | |
| 55 | 45 | assert(not_global_f); |
| 56 | 46 | assert(!not_global_t); |
| 57 | 47 | } |
test/cases/cast.zig+3-9| ... | ... | @@ -1,24 +1,18 @@ |
| 1 | 1 | const assert = @import("std").debug.assert; |
| 2 | 2 | |
| 3 | fn intToPtrCast() { | |
| 4 | @setFnTest(this); | |
| 5 | ||
| 3 | test "intToPtrCast" { | |
| 6 | 4 | const x = isize(13); |
| 7 | 5 | const y = (&u8)(x); |
| 8 | 6 | const z = usize(y); |
| 9 | 7 | assert(z == 13); |
| 10 | 8 | } |
| 11 | 9 | |
| 12 | fn numLitIntToPtrCast() { | |
| 13 | @setFnTest(this); | |
| 14 | ||
| 10 | test "numLitIntToPtrCast" { | |
| 15 | 11 | const vga_mem = (&u16)(0xB8000); |
| 16 | 12 | assert(usize(vga_mem) == 0xB8000); |
| 17 | 13 | } |
| 18 | 14 | |
| 19 | fn pointerReinterpretConstFloatToInt() { | |
| 20 | @setFnTest(this); | |
| 21 | ||
| 15 | test "pointerReinterpretConstFloatToInt" { | |
| 22 | 16 | const float: f64 = 5.99999999999994648725e-01; |
| 23 | 17 | const float_ptr = &float; |
| 24 | 18 | const int_ptr = (&i32)(float_ptr); |
test/cases/const_slice_child.zig+1-3| ... | ... | @@ -2,9 +2,7 @@ const assert = @import("std").debug.assert; |
| 2 | 2 | |
| 3 | 3 | var argv: &const &const u8 = undefined; |
| 4 | 4 | |
| 5 | fn constSliceChild() { | |
| 6 | @setFnTest(this); | |
| 7 | ||
| 5 | test "constSliceChild" { | |
| 8 | 6 | const strs = ([]&const u8) { |
| 9 | 7 | c"one", |
| 10 | 8 | c"two", |
test/cases/defer.zig+2-6| ... | ... | @@ -21,9 +21,7 @@ fn runSomeMaybeDefers(x: bool) -> ?bool { |
| 21 | 21 | return if (x) x else null; |
| 22 | 22 | } |
| 23 | 23 | |
| 24 | fn mixingNormalAndErrorDefers() { | |
| 25 | @setFnTest(this); | |
| 26 | ||
| 24 | test "mixingNormalAndErrorDefers" { | |
| 27 | 25 | assert(%%runSomeErrorDefers(true)); |
| 28 | 26 | assert(result[0] == 'c'); |
| 29 | 27 | assert(result[1] == 'a'); |
| ... | ... | @@ -38,9 +36,7 @@ fn mixingNormalAndErrorDefers() { |
| 38 | 36 | assert(result[2] == 'a'); |
| 39 | 37 | } |
| 40 | 38 | |
| 41 | fn mixingNormalAndMaybeDefers() { | |
| 42 | @setFnTest(this); | |
| 43 | ||
| 39 | test "mixingNormalAndMaybeDefers" { | |
| 44 | 40 | assert(??runSomeMaybeDefers(true)); |
| 45 | 41 | assert(result[0] == 'c'); |
| 46 | 42 | assert(result[1] == 'a'); |
test/cases/enum.zig+5-15| ... | ... | @@ -1,8 +1,6 @@ |
| 1 | 1 | const assert = @import("std").debug.assert; |
| 2 | 2 | |
| 3 | fn enumType() { | |
| 4 | @setFnTest(this); | |
| 5 | ||
| 3 | test "enumType" { | |
| 6 | 4 | const foo1 = Foo.One {13}; |
| 7 | 5 | const foo2 = Foo.Two { Point { .x = 1234, .y = 5678, }}; |
| 8 | 6 | const bar = Bar.B; |
| ... | ... | @@ -15,9 +13,7 @@ fn enumType() { |
| 15 | 13 | assert(@sizeOf(Bar) == 1); |
| 16 | 14 | } |
| 17 | 15 | |
| 18 | fn enumAsReturnValue () { | |
| 19 | @setFnTest(this); | |
| 20 | ||
| 16 | test "enumAsReturnValue" { | |
| 21 | 17 | switch (returnAnInt(13)) { |
| 22 | 18 | Foo.One => |value| assert(value == 13), |
| 23 | 19 | else => @unreachable(), |
| ... | ... | @@ -45,9 +41,7 @@ fn returnAnInt(x: i32) -> Foo { |
| 45 | 41 | } |
| 46 | 42 | |
| 47 | 43 | |
| 48 | fn constantEnumWithPayload() { | |
| 49 | @setFnTest(this); | |
| 50 | ||
| 44 | test "constantEnumWithPayload" { | |
| 51 | 45 | var empty = AnEnumWithPayload.Empty; |
| 52 | 46 | var full = AnEnumWithPayload.Full {13}; |
| 53 | 47 | shouldBeEmpty(empty); |
| ... | ... | @@ -83,9 +77,7 @@ const Number = enum { |
| 83 | 77 | Four, |
| 84 | 78 | }; |
| 85 | 79 | |
| 86 | fn enumToInt() { | |
| 87 | @setFnTest(this); | |
| 88 | ||
| 80 | test "enumToInt" { | |
| 89 | 81 | shouldEqual(Number.Zero, 0); |
| 90 | 82 | shouldEqual(Number.One, 1); |
| 91 | 83 | shouldEqual(Number.Two, 2); |
| ... | ... | @@ -98,9 +90,7 @@ fn shouldEqual(n: Number, expected: usize) { |
| 98 | 90 | } |
| 99 | 91 | |
| 100 | 92 | |
| 101 | fn intToEnum() { | |
| 102 | @setFnTest(this); | |
| 103 | ||
| 93 | test "intToEnum" { | |
| 104 | 94 | testIntToEnumEval(3); |
| 105 | 95 | } |
| 106 | 96 | fn testIntToEnumEval(x: i32) { |
test/cases/enum_with_members.zig+1-3| ... | ... | @@ -14,9 +14,7 @@ const ET = enum { |
| 14 | 14 | } |
| 15 | 15 | }; |
| 16 | 16 | |
| 17 | fn enumWithMembers() { | |
| 18 | @setFnTest(this); | |
| 19 | ||
| 17 | test "enumWithMembers" { | |
| 20 | 18 | const a = ET.SINT { -42 }; |
| 21 | 19 | const b = ET.UINT { 42 }; |
| 22 | 20 | var buf: [20]u8 = undefined; |
test/cases/error.zig+7-20| ... | ... | @@ -15,9 +15,7 @@ pub fn baz() -> %i32 { |
| 15 | 15 | return y + 1; |
| 16 | 16 | } |
| 17 | 17 | |
| 18 | fn errorWrapping() { | |
| 19 | @setFnTest(this); | |
| 20 | ||
| 18 | test "errorWrapping" { | |
| 21 | 19 | assert(%%baz() == 15); |
| 22 | 20 | } |
| 23 | 21 | |
| ... | ... | @@ -26,8 +24,7 @@ fn gimmeItBroke() -> []const u8 { |
| 26 | 24 | @errorName(error.ItBroke) |
| 27 | 25 | } |
| 28 | 26 | |
| 29 | fn errorName() { | |
| 30 | @setFnTest(this); | |
| 27 | test "errorName" { | |
| 31 | 28 | assert(mem.eql(u8, @errorName(error.AnError), "AnError")); |
| 32 | 29 | assert(mem.eql(u8, @errorName(error.ALongerErrorName), "ALongerErrorName")); |
| 33 | 30 | } |
| ... | ... | @@ -35,9 +32,7 @@ error AnError; |
| 35 | 32 | error ALongerErrorName; |
| 36 | 33 | |
| 37 | 34 | |
| 38 | fn errorValues() { | |
| 39 | @setFnTest(this); | |
| 40 | ||
| 35 | test "errorValues" { | |
| 41 | 36 | const a = i32(error.err1); |
| 42 | 37 | const b = i32(error.err2); |
| 43 | 38 | assert(a != b); |
| ... | ... | @@ -46,9 +41,7 @@ error err1; |
| 46 | 41 | error err2; |
| 47 | 42 | |
| 48 | 43 | |
| 49 | fn redefinitionOfErrorValuesAllowed() { | |
| 50 | @setFnTest(this); | |
| 51 | ||
| 44 | test "redefinitionOfErrorValuesAllowed" { | |
| 52 | 45 | shouldBeNotEqual(error.AnError, error.SecondError); |
| 53 | 46 | } |
| 54 | 47 | error AnError; |
| ... | ... | @@ -59,9 +52,7 @@ fn shouldBeNotEqual(a: error, b: error) { |
| 59 | 52 | } |
| 60 | 53 | |
| 61 | 54 | |
| 62 | fn errBinaryOperator() { | |
| 63 | @setFnTest(this); | |
| 64 | ||
| 55 | test "errBinaryOperator" { | |
| 65 | 56 | const a = errBinaryOperatorG(true) %% 3; |
| 66 | 57 | const b = errBinaryOperatorG(false) %% 3; |
| 67 | 58 | assert(a == 3); |
| ... | ... | @@ -77,18 +68,14 @@ fn errBinaryOperatorG(x: bool) -> %isize { |
| 77 | 68 | } |
| 78 | 69 | |
| 79 | 70 | |
| 80 | fn unwrapSimpleValueFromError() { | |
| 81 | @setFnTest(this); | |
| 82 | ||
| 71 | test "unwrapSimpleValueFromError" { | |
| 83 | 72 | const i = %%unwrapSimpleValueFromErrorDo(); |
| 84 | 73 | assert(i == 13); |
| 85 | 74 | } |
| 86 | 75 | fn unwrapSimpleValueFromErrorDo() -> %isize { 13 } |
| 87 | 76 | |
| 88 | 77 | |
| 89 | fn errReturnInAssignment() { | |
| 90 | @setFnTest(this); | |
| 91 | ||
| 78 | test "errReturnInAssignment" { | |
| 92 | 79 | %%doErrReturnInAssignment(); |
| 93 | 80 | } |
| 94 | 81 |
test/cases/eval.zig+19-55| ... | ... | @@ -1,8 +1,6 @@ |
| 1 | 1 | const assert = @import("std").debug.assert; |
| 2 | 2 | |
| 3 | fn compileTimeRecursion() { | |
| 4 | @setFnTest(this); | |
| 5 | ||
| 3 | test "compileTimeRecursion" { | |
| 6 | 4 | assert(some_data.len == 21); |
| 7 | 5 | } |
| 8 | 6 | var some_data: [usize(fibonacci(7))]u8 = undefined; |
| ... | ... | @@ -17,14 +15,11 @@ fn unwrapAndAddOne(blah: ?i32) -> i32 { |
| 17 | 15 | return ??blah + 1; |
| 18 | 16 | } |
| 19 | 17 | const should_be_1235 = unwrapAndAddOne(1234); |
| 20 | fn testStaticAddOne() { | |
| 21 | @setFnTest(this); | |
| 18 | test "testStaticAddOne" { | |
| 22 | 19 | assert(should_be_1235 == 1235); |
| 23 | 20 | } |
| 24 | 21 | |
| 25 | fn inlinedLoop() { | |
| 26 | @setFnTest(this); | |
| 27 | ||
| 22 | test "inlinedLoop" { | |
| 28 | 23 | comptime var i = 0; |
| 29 | 24 | comptime var sum = 0; |
| 30 | 25 | inline while (i <= 5; i += 1) |
| ... | ... | @@ -38,25 +33,20 @@ fn gimme1or2(comptime a: bool) -> i32 { |
| 38 | 33 | comptime var z: i32 = if (a) x else y; |
| 39 | 34 | return z; |
| 40 | 35 | } |
| 41 | fn inlineVariableGetsResultOfConstIf() { | |
| 42 | @setFnTest(this); | |
| 36 | test "inlineVariableGetsResultOfConstIf" { | |
| 43 | 37 | assert(gimme1or2(true) == 1); |
| 44 | 38 | assert(gimme1or2(false) == 2); |
| 45 | 39 | } |
| 46 | 40 | |
| 47 | 41 | |
| 48 | fn staticFunctionEvaluation() { | |
| 49 | @setFnTest(this); | |
| 50 | ||
| 42 | test "staticFunctionEvaluation" { | |
| 51 | 43 | assert(statically_added_number == 3); |
| 52 | 44 | } |
| 53 | 45 | const statically_added_number = staticAdd(1, 2); |
| 54 | 46 | fn staticAdd(a: i32, b: i32) -> i32 { a + b } |
| 55 | 47 | |
| 56 | 48 | |
| 57 | fn constExprEvalOnSingleExprBlocks() { | |
| 58 | @setFnTest(this); | |
| 59 | ||
| 49 | test "constExprEvalOnSingleExprBlocks" { | |
| 60 | 50 | assert(constExprEvalOnSingleExprBlocksFn(1, true) == 3); |
| 61 | 51 | } |
| 62 | 52 | |
| ... | ... | @@ -75,9 +65,7 @@ fn constExprEvalOnSingleExprBlocksFn(x: i32, b: bool) -> i32 { |
| 75 | 65 | |
| 76 | 66 | |
| 77 | 67 | |
| 78 | fn staticallyInitalizedList() { | |
| 79 | @setFnTest(this); | |
| 80 | ||
| 68 | test "staticallyInitalizedList" { | |
| 81 | 69 | assert(static_point_list[0].x == 1); |
| 82 | 70 | assert(static_point_list[0].y == 2); |
| 83 | 71 | assert(static_point_list[1].x == 3); |
| ... | ... | @@ -96,9 +84,7 @@ fn makePoint(x: i32, y: i32) -> Point { |
| 96 | 84 | } |
| 97 | 85 | |
| 98 | 86 | |
| 99 | fn staticEvalListInit() { | |
| 100 | @setFnTest(this); | |
| 101 | ||
| 87 | test "staticEvalListInit" { | |
| 102 | 88 | assert(static_vec3.data[2] == 1.0); |
| 103 | 89 | assert(vec3(0.0, 0.0, 3.0).data[2] == 3.0); |
| 104 | 90 | } |
| ... | ... | @@ -113,18 +99,14 @@ pub fn vec3(x: f32, y: f32, z: f32) -> Vec3 { |
| 113 | 99 | } |
| 114 | 100 | |
| 115 | 101 | |
| 116 | fn constantExpressions() { | |
| 117 | @setFnTest(this); | |
| 118 | ||
| 102 | test "constantExpressions" { | |
| 119 | 103 | var array : [array_size]u8 = undefined; |
| 120 | 104 | assert(@sizeOf(@typeOf(array)) == 20); |
| 121 | 105 | } |
| 122 | 106 | const array_size : u8 = 20; |
| 123 | 107 | |
| 124 | 108 | |
| 125 | fn constantStructWithNegation() { | |
| 126 | @setFnTest(this); | |
| 127 | ||
| 109 | test "constantStructWithNegation" { | |
| 128 | 110 | assert(vertices[0].x == -0.6); |
| 129 | 111 | } |
| 130 | 112 | const Vertex = struct { |
| ... | ... | @@ -141,9 +123,7 @@ const vertices = []Vertex { |
| 141 | 123 | }; |
| 142 | 124 | |
| 143 | 125 | |
| 144 | fn staticallyInitalizedStruct() { | |
| 145 | @setFnTest(this); | |
| 146 | ||
| 126 | test "staticallyInitalizedStruct" { | |
| 147 | 127 | st_init_str_foo.x += 1; |
| 148 | 128 | assert(st_init_str_foo.x == 14); |
| 149 | 129 | } |
| ... | ... | @@ -154,18 +134,14 @@ const StInitStrFoo = struct { |
| 154 | 134 | var st_init_str_foo = StInitStrFoo { .x = 13, .y = true, }; |
| 155 | 135 | |
| 156 | 136 | |
| 157 | fn staticallyInitializedArrayLiteral() { | |
| 158 | @setFnTest(this); | |
| 159 | ||
| 137 | test "staticallyInitializedArrayLiteral" { | |
| 160 | 138 | const y : [4]u8 = st_init_arr_lit_x; |
| 161 | 139 | assert(y[3] == 4); |
| 162 | 140 | } |
| 163 | 141 | const st_init_arr_lit_x = []u8{1,2,3,4}; |
| 164 | 142 | |
| 165 | 143 | |
| 166 | fn constSlice() { | |
| 167 | @setFnTest(this); | |
| 168 | ||
| 144 | test "constSlice" { | |
| 169 | 145 | comptime { |
| 170 | 146 | const a = "1234567890"; |
| 171 | 147 | assert(a.len == 10); |
| ... | ... | @@ -175,9 +151,7 @@ fn constSlice() { |
| 175 | 151 | } |
| 176 | 152 | } |
| 177 | 153 | |
| 178 | fn tryToTrickEvalWithRuntimeIf() { | |
| 179 | @setFnTest(this); | |
| 180 | ||
| 154 | test "tryToTrickEvalWithRuntimeIf" { | |
| 181 | 155 | assert(testTryToTrickEvalWithRuntimeIf(true) == 10); |
| 182 | 156 | } |
| 183 | 157 | |
| ... | ... | @@ -203,9 +177,7 @@ fn max(comptime T: type, a: T, b: T) -> T { |
| 203 | 177 | fn letsTryToCompareBools(a: bool, b: bool) -> bool { |
| 204 | 178 | max(bool, a, b) |
| 205 | 179 | } |
| 206 | fn inlinedBlockAndRuntimeBlockPhi() { | |
| 207 | @setFnTest(this); | |
| 208 | ||
| 180 | test "inlinedBlockAndRuntimeBlockPhi" { | |
| 209 | 181 | assert(letsTryToCompareBools(true, true)); |
| 210 | 182 | assert(letsTryToCompareBools(true, false)); |
| 211 | 183 | assert(letsTryToCompareBools(false, true)); |
| ... | ... | @@ -244,17 +216,13 @@ fn performFn(comptime prefix_char: u8, start_value: i32) -> i32 { |
| 244 | 216 | return result; |
| 245 | 217 | } |
| 246 | 218 | |
| 247 | fn comptimeIterateOverFnPtrList() { | |
| 248 | @setFnTest(this); | |
| 249 | ||
| 219 | test "comptimeIterateOverFnPtrList" { | |
| 250 | 220 | assert(performFn('t', 1) == 6); |
| 251 | 221 | assert(performFn('o', 0) == 1); |
| 252 | 222 | assert(performFn('w', 99) == 99); |
| 253 | 223 | } |
| 254 | 224 | |
| 255 | fn evalSetDebugSafetyAtCompileTime() { | |
| 256 | @setFnTest(this); | |
| 257 | ||
| 225 | test "evalSetDebugSafetyAtCompileTime" { | |
| 258 | 226 | const result = comptime fnWithSetDebugSafety(); |
| 259 | 227 | assert(result == 1234); |
| 260 | 228 | } |
| ... | ... | @@ -278,17 +246,13 @@ var simple_struct = SimpleStruct{ .field = 1234, }; |
| 278 | 246 | |
| 279 | 247 | const bound_fn = simple_struct.method; |
| 280 | 248 | |
| 281 | fn callMethodOnBoundFnReferringToVarInstance() { | |
| 282 | @setFnTest(this); | |
| 283 | ||
| 249 | test "callMethodOnBoundFnReferringToVarInstance" { | |
| 284 | 250 | assert(bound_fn() == 1237); |
| 285 | 251 | } |
| 286 | 252 | |
| 287 | 253 | |
| 288 | 254 | |
| 289 | fn ptrToLocalArrayArgumentAtComptime() { | |
| 290 | @setFnTest(this); | |
| 291 | ||
| 255 | test "ptrToLocalArrayArgumentAtComptime" { | |
| 292 | 256 | comptime { |
| 293 | 257 | var bytes: [10]u8 = undefined; |
| 294 | 258 | modifySomeBytes(bytes[0...]); |
test/cases/fn.zig+13-26| ... | ... | @@ -1,8 +1,6 @@ |
| 1 | 1 | const assert = @import("std").debug.assert; |
| 2 | 2 | |
| 3 | fn params() { | |
| 4 | @setFnTest(this); | |
| 5 | ||
| 3 | test "params" { | |
| 6 | 4 | assert(testParamsAdd(22, 11) == 33); |
| 7 | 5 | } |
| 8 | 6 | fn testParamsAdd(a: i32, b: i32) -> i32 { |
| ... | ... | @@ -10,9 +8,7 @@ fn testParamsAdd(a: i32, b: i32) -> i32 { |
| 10 | 8 | } |
| 11 | 9 | |
| 12 | 10 | |
| 13 | fn localVariables() { | |
| 14 | @setFnTest(this); | |
| 15 | ||
| 11 | test "localVariables" { | |
| 16 | 12 | testLocVars(2); |
| 17 | 13 | } |
| 18 | 14 | fn testLocVars(b: i32) { |
| ... | ... | @@ -21,9 +17,7 @@ fn testLocVars(b: i32) { |
| 21 | 17 | } |
| 22 | 18 | |
| 23 | 19 | |
| 24 | fn voidParameters() { | |
| 25 | @setFnTest(this); | |
| 26 | ||
| 20 | test "voidParameters" { | |
| 27 | 21 | voidFun(1, void{}, 2, {}); |
| 28 | 22 | } |
| 29 | 23 | fn voidFun(a: i32, b: void, c: i32, d: void) { |
| ... | ... | @@ -34,9 +28,7 @@ fn voidFun(a: i32, b: void, c: i32, d: void) { |
| 34 | 28 | } |
| 35 | 29 | |
| 36 | 30 | |
| 37 | fn mutableLocalVariables() { | |
| 38 | @setFnTest(this); | |
| 39 | ||
| 31 | test "mutableLocalVariables" { | |
| 40 | 32 | var zero : i32 = 0; |
| 41 | 33 | assert(zero == 0); |
| 42 | 34 | |
| ... | ... | @@ -47,9 +39,7 @@ fn mutableLocalVariables() { |
| 47 | 39 | assert(i == 3); |
| 48 | 40 | } |
| 49 | 41 | |
| 50 | fn separateBlockScopes() { | |
| 51 | @setFnTest(this); | |
| 52 | ||
| 42 | test "separateBlockScopes" { | |
| 53 | 43 | { |
| 54 | 44 | const no_conflict : i32 = 5; |
| 55 | 45 | assert(no_conflict == 5); |
| ... | ... | @@ -62,22 +52,21 @@ fn separateBlockScopes() { |
| 62 | 52 | assert(c == 10); |
| 63 | 53 | } |
| 64 | 54 | |
| 65 | fn callFnWithEmptyString() { | |
| 66 | @setFnTest(this); | |
| 67 | ||
| 55 | test "callFnWithEmptyString" { | |
| 68 | 56 | acceptsString(""); |
| 69 | 57 | } |
| 70 | 58 | |
| 71 | 59 | fn acceptsString(foo: []u8) { } |
| 72 | 60 | |
| 73 | 61 | |
| 74 | fn @"weird function name"() { | |
| 75 | @setFnTest(this); | |
| 62 | fn @"weird function name"() -> i32 { | |
| 63 | return 1234; | |
| 64 | } | |
| 65 | test "weird function name" { | |
| 66 | assert(@"weird function name"() == 1234); | |
| 76 | 67 | } |
| 77 | 68 | |
| 78 | fn implicitCastFnUnreachableReturn() { | |
| 79 | @setFnTest(this); | |
| 80 | ||
| 69 | test "implicitCastFnUnreachableReturn" { | |
| 81 | 70 | wantsFnWithVoid(fnWithUnreachable); |
| 82 | 71 | } |
| 83 | 72 | |
| ... | ... | @@ -88,9 +77,7 @@ fn fnWithUnreachable() -> unreachable { |
| 88 | 77 | } |
| 89 | 78 | |
| 90 | 79 | |
| 91 | fn functionPointers() { | |
| 92 | @setFnTest(this); | |
| 93 | ||
| 80 | test "functionPointers" { | |
| 94 | 81 | const fns = []@typeOf(fn1) { fn1, fn2, fn3, fn4, }; |
| 95 | 82 | for (fns) |f, i| { |
| 96 | 83 | assert(f() == u32(i) + 5); |
test/cases/for.zig+3-9| ... | ... | @@ -2,9 +2,7 @@ const std = @import("std"); |
| 2 | 2 | const assert = std.debug.assert; |
| 3 | 3 | const mem = std.mem; |
| 4 | 4 | |
| 5 | fn continueInForLoop() { | |
| 6 | @setFnTest(this); | |
| 7 | ||
| 5 | test "continueInForLoop" { | |
| 8 | 6 | const array = []i32 {1, 2, 3, 4, 5}; |
| 9 | 7 | var sum : i32 = 0; |
| 10 | 8 | for (array) |x| { |
| ... | ... | @@ -17,9 +15,7 @@ fn continueInForLoop() { |
| 17 | 15 | if (sum != 6) @unreachable() |
| 18 | 16 | } |
| 19 | 17 | |
| 20 | fn forLoopWithPointerElemVar() { | |
| 21 | @setFnTest(this); | |
| 22 | ||
| 18 | test "forLoopWithPointerElemVar" { | |
| 23 | 19 | const source = "abcdefg"; |
| 24 | 20 | var target: [source.len]u8 = undefined; |
| 25 | 21 | mem.copy(u8, target[0...], source); |
| ... | ... | @@ -32,9 +28,7 @@ fn mangleString(s: []u8) { |
| 32 | 28 | } |
| 33 | 29 | } |
| 34 | 30 | |
| 35 | fn basicForLoop() { | |
| 36 | @setFnTest(this); | |
| 37 | ||
| 31 | test "basicForLoop" { | |
| 38 | 32 | const expected_result = []u8{9, 8, 7, 6, 0, 1, 2, 3, 9, 8, 7, 6, 0, 1, 2, 3 }; |
| 39 | 33 | |
| 40 | 34 | var buffer: [expected_result.len]u8 = undefined; |
test/cases/generics.zig+9-26| ... | ... | @@ -1,8 +1,6 @@ |
| 1 | 1 | const assert = @import("std").debug.assert; |
| 2 | 2 | |
| 3 | fn simpleGenericFn() { | |
| 4 | @setFnTest(this); | |
| 5 | ||
| 3 | test "simpleGenericFn" { | |
| 6 | 4 | assert(max(i32, 3, -1) == 3); |
| 7 | 5 | assert(max(f32, 0.123, 0.456) == 0.456); |
| 8 | 6 | assert(add(2, 3) == 5); |
| ... | ... | @@ -17,8 +15,7 @@ fn add(comptime a: i32, b: i32) -> i32 { |
| 17 | 15 | } |
| 18 | 16 | |
| 19 | 17 | const the_max = max(u32, 1234, 5678); |
| 20 | fn compileTimeGenericEval() { | |
| 21 | @setFnTest(this); | |
| 18 | test "compileTimeGenericEval" { | |
| 22 | 19 | assert(the_max == 5678); |
| 23 | 20 | } |
| 24 | 21 | |
| ... | ... | @@ -34,18 +31,14 @@ fn sameButWithFloats(a: f64, b: f64) -> f64 { |
| 34 | 31 | max(f64, a, b) |
| 35 | 32 | } |
| 36 | 33 | |
| 37 | fn fnWithInlineArgs() { | |
| 38 | @setFnTest(this); | |
| 39 | ||
| 34 | test "fnWithInlineArgs" { | |
| 40 | 35 | assert(gimmeTheBigOne(1234, 5678) == 5678); |
| 41 | 36 | assert(shouldCallSameInstance(34, 12) == 34); |
| 42 | 37 | assert(sameButWithFloats(0.43, 0.49) == 0.49); |
| 43 | 38 | } |
| 44 | 39 | |
| 45 | 40 | |
| 46 | fn varParams() { | |
| 47 | @setFnTest(this); | |
| 48 | ||
| 41 | test "varParams" { | |
| 49 | 42 | assert(max_i32(12, 34) == 34); |
| 50 | 43 | assert(max_f64(1.2, 3.4) == 3.4); |
| 51 | 44 | } |
| ... | ... | @@ -79,9 +72,7 @@ pub fn SmallList(comptime T: type, comptime STATIC_SIZE: usize) -> type { |
| 79 | 72 | } |
| 80 | 73 | } |
| 81 | 74 | |
| 82 | fn functionWithReturnTypeType() { | |
| 83 | @setFnTest(this); | |
| 84 | ||
| 75 | test "functionWithReturnTypeType" { | |
| 85 | 76 | var list: List(i32) = undefined; |
| 86 | 77 | var list2: List(i32) = undefined; |
| 87 | 78 | list.length = 10; |
| ... | ... | @@ -91,9 +82,7 @@ fn functionWithReturnTypeType() { |
| 91 | 82 | } |
| 92 | 83 | |
| 93 | 84 | |
| 94 | fn genericStruct() { | |
| 95 | @setFnTest(this); | |
| 96 | ||
| 85 | test "genericStruct" { | |
| 97 | 86 | var a1 = GenNode(i32) {.value = 13, .next = null,}; |
| 98 | 87 | var b1 = GenNode(bool) {.value = true, .next = null,}; |
| 99 | 88 | assert(a1.value == 13); |
| ... | ... | @@ -108,9 +97,7 @@ fn GenNode(comptime T: type) -> type { |
| 108 | 97 | } |
| 109 | 98 | } |
| 110 | 99 | |
| 111 | fn constDeclsInStruct() { | |
| 112 | @setFnTest(this); | |
| 113 | ||
| 100 | test "constDeclsInStruct" { | |
| 114 | 101 | assert(GenericDataThing(3).count_plus_one == 4); |
| 115 | 102 | } |
| 116 | 103 | fn GenericDataThing(comptime count: isize) -> type { |
| ... | ... | @@ -120,9 +107,7 @@ fn GenericDataThing(comptime count: isize) -> type { |
| 120 | 107 | } |
| 121 | 108 | |
| 122 | 109 | |
| 123 | fn useGenericParamInGenericParam() { | |
| 124 | @setFnTest(this); | |
| 125 | ||
| 110 | test "useGenericParamInGenericParam" { | |
| 126 | 111 | assert(aGenericFn(i32, 3, 4) == 7); |
| 127 | 112 | } |
| 128 | 113 | fn aGenericFn(comptime T: type, comptime a: T, b: T) -> T { |
| ... | ... | @@ -130,9 +115,7 @@ fn aGenericFn(comptime T: type, comptime a: T, b: T) -> T { |
| 130 | 115 | } |
| 131 | 116 | |
| 132 | 117 | |
| 133 | fn genericFnWithImplicitCast() { | |
| 134 | @setFnTest(this); | |
| 135 | ||
| 118 | test "genericFnWithImplicitCast" { | |
| 136 | 119 | assert(getFirstByte(u8, []u8 {13}) == 13); |
| 137 | 120 | assert(getFirstByte(u16, []u16 {0, 13}) == 0); |
| 138 | 121 | } |
test/cases/goto.zig+2-6| ... | ... | @@ -1,8 +1,6 @@ |
| 1 | 1 | const assert = @import("std").debug.assert; |
| 2 | 2 | |
| 3 | fn gotoAndLabels() { | |
| 4 | @setFnTest(this); | |
| 5 | ||
| 3 | test "gotoAndLabels" { | |
| 6 | 4 | gotoLoop(); |
| 7 | 5 | assert(goto_counter == 10); |
| 8 | 6 | } |
| ... | ... | @@ -21,9 +19,7 @@ var goto_counter: i32 = 0; |
| 21 | 19 | |
| 22 | 20 | |
| 23 | 21 | |
| 24 | fn gotoLeaveDeferScope() { | |
| 25 | @setFnTest(this); | |
| 26 | ||
| 22 | test "gotoLeaveDeferScope" { | |
| 27 | 23 | testGotoLeaveDeferScope(true); |
| 28 | 24 | } |
| 29 | 25 | fn testGotoLeaveDeferScope(b: bool) { |
test/cases/if.zig+2-6| ... | ... | @@ -1,8 +1,6 @@ |
| 1 | 1 | const assert = @import("std").debug.assert; |
| 2 | 2 | |
| 3 | fn ifStatements() { | |
| 4 | @setFnTest(this); | |
| 5 | ||
| 3 | test "ifStatements" { | |
| 6 | 4 | shouldBeEqual(1, 1); |
| 7 | 5 | firstEqlThird(2, 1, 2); |
| 8 | 6 | } |
| ... | ... | @@ -26,9 +24,7 @@ fn firstEqlThird(a: i32, b: i32, c: i32) { |
| 26 | 24 | } |
| 27 | 25 | |
| 28 | 26 | |
| 29 | fn elseIfExpression() { | |
| 30 | @setFnTest(this); | |
| 31 | ||
| 27 | test "elseIfExpression" { | |
| 32 | 28 | assert(elseIfExpressionF(1) == 1); |
| 33 | 29 | } |
| 34 | 30 | fn elseIfExpressionF(c: u8) -> u8 { |
test/cases/import.zig+1-3| ... | ... | @@ -1,8 +1,6 @@ |
| 1 | 1 | const assert = @import("std").debug.assert; |
| 2 | 2 | const a_namespace = @import("cases/import/a_namespace.zig"); |
| 3 | 3 | |
| 4 | fn callFnViaNamespaceLookup() { | |
| 5 | @setFnTest(this); | |
| 6 | ||
| 4 | test "callFnViaNamespaceLookup" { | |
| 7 | 5 | assert(a_namespace.foo() == 1234); |
| 8 | 6 | } |
test/cases/ir_block_deps.zig+1-3| ... | ... | @@ -15,9 +15,7 @@ fn getErrInt() -> %i32 { 0 } |
| 15 | 15 | |
| 16 | 16 | error ItBroke; |
| 17 | 17 | |
| 18 | fn irBlockDeps() { | |
| 19 | @setFnTest(this); | |
| 20 | ||
| 18 | test "irBlockDeps" { | |
| 21 | 19 | assert(%%foo(1) == 0); |
| 22 | 20 | assert(%%foo(2) == 0); |
| 23 | 21 | } |
test/cases/math.zig+17-51| ... | ... | @@ -1,60 +1,46 @@ |
| 1 | 1 | const assert = @import("std").debug.assert; |
| 2 | 2 | |
| 3 | fn exactDivision() { | |
| 4 | @setFnTest(this); | |
| 5 | ||
| 3 | test "exactDivision" { | |
| 6 | 4 | assert(divExact(55, 11) == 5); |
| 7 | 5 | } |
| 8 | 6 | fn divExact(a: u32, b: u32) -> u32 { |
| 9 | 7 | @divExact(a, b) |
| 10 | 8 | } |
| 11 | 9 | |
| 12 | fn floatDivision() { | |
| 13 | @setFnTest(this); | |
| 14 | ||
| 10 | test "floatDivision" { | |
| 15 | 11 | assert(fdiv32(12.0, 3.0) == 4.0); |
| 16 | 12 | } |
| 17 | 13 | fn fdiv32(a: f32, b: f32) -> f32 { |
| 18 | 14 | a / b |
| 19 | 15 | } |
| 20 | 16 | |
| 21 | fn overflowIntrinsics() { | |
| 22 | @setFnTest(this); | |
| 23 | ||
| 17 | test "overflowIntrinsics" { | |
| 24 | 18 | var result: u8 = undefined; |
| 25 | 19 | assert(@addWithOverflow(u8, 250, 100, &result)); |
| 26 | 20 | assert(!@addWithOverflow(u8, 100, 150, &result)); |
| 27 | 21 | assert(result == 250); |
| 28 | 22 | } |
| 29 | 23 | |
| 30 | fn shlWithOverflow() { | |
| 31 | @setFnTest(this); | |
| 32 | ||
| 24 | test "shlWithOverflow" { | |
| 33 | 25 | var result: u16 = undefined; |
| 34 | 26 | assert(@shlWithOverflow(u16, 0b0010111111111111, 3, &result)); |
| 35 | 27 | assert(!@shlWithOverflow(u16, 0b0010111111111111, 2, &result)); |
| 36 | 28 | assert(result == 0b1011111111111100); |
| 37 | 29 | } |
| 38 | 30 | |
| 39 | fn countLeadingZeroes() { | |
| 40 | @setFnTest(this); | |
| 41 | ||
| 31 | test "countLeadingZeroes" { | |
| 42 | 32 | assert(@clz(u8(0b00001010)) == 4); |
| 43 | 33 | assert(@clz(u8(0b10001010)) == 0); |
| 44 | 34 | assert(@clz(u8(0b00000000)) == 8); |
| 45 | 35 | } |
| 46 | 36 | |
| 47 | fn countTrailingZeroes() { | |
| 48 | @setFnTest(this); | |
| 49 | ||
| 37 | test "countTrailingZeroes" { | |
| 50 | 38 | assert(@ctz(u8(0b10100000)) == 5); |
| 51 | 39 | assert(@ctz(u8(0b10001010)) == 1); |
| 52 | 40 | assert(@ctz(u8(0b00000000)) == 8); |
| 53 | 41 | } |
| 54 | 42 | |
| 55 | fn modifyOperators() { | |
| 56 | @setFnTest(this); | |
| 57 | ||
| 43 | test "modifyOperators" { | |
| 58 | 44 | var i : i32 = 0; |
| 59 | 45 | i += 5; assert(i == 5); |
| 60 | 46 | i -= 2; assert(i == 3); |
| ... | ... | @@ -70,9 +56,7 @@ fn modifyOperators() { |
| 70 | 56 | i |= 3; assert(i == 7); |
| 71 | 57 | } |
| 72 | 58 | |
| 73 | fn threeExprInARow() { | |
| 74 | @setFnTest(this); | |
| 75 | testThreeExprInARow(false, true); | |
| 59 | test "threeExprInARow" { | |
| 76 | 60 | } |
| 77 | 61 | fn testThreeExprInARow(f: bool, t: bool) { |
| 78 | 62 | assertFalse(f || f || f); |
| ... | ... | @@ -94,9 +78,7 @@ fn assertFalse(b: bool) { |
| 94 | 78 | } |
| 95 | 79 | |
| 96 | 80 | |
| 97 | fn constNumberLiteral() { | |
| 98 | @setFnTest(this); | |
| 99 | ||
| 81 | test "constNumberLiteral" { | |
| 100 | 82 | const one = 1; |
| 101 | 83 | const eleven = ten + one; |
| 102 | 84 | |
| ... | ... | @@ -106,9 +88,7 @@ const ten = 10; |
| 106 | 88 | |
| 107 | 89 | |
| 108 | 90 | |
| 109 | fn unsignedWrapping() { | |
| 110 | @setFnTest(this); | |
| 111 | ||
| 91 | test "unsignedWrapping" { | |
| 112 | 92 | testUnsignedWrappingEval(@maxValue(u32)); |
| 113 | 93 | } |
| 114 | 94 | fn testUnsignedWrappingEval(x: u32) { |
| ... | ... | @@ -118,9 +98,7 @@ fn testUnsignedWrappingEval(x: u32) { |
| 118 | 98 | assert(orig == @maxValue(u32)); |
| 119 | 99 | } |
| 120 | 100 | |
| 121 | fn signedWrapping() { | |
| 122 | @setFnTest(this); | |
| 123 | ||
| 101 | test "signedWrapping" { | |
| 124 | 102 | testSignedWrappingEval(@maxValue(i32)); |
| 125 | 103 | } |
| 126 | 104 | fn testSignedWrappingEval(x: i32) { |
| ... | ... | @@ -130,9 +108,7 @@ fn testSignedWrappingEval(x: i32) { |
| 130 | 108 | assert(max_val == @maxValue(i32)); |
| 131 | 109 | } |
| 132 | 110 | |
| 133 | fn negationWrapping() { | |
| 134 | @setFnTest(this); | |
| 135 | ||
| 111 | test "negationWrapping" { | |
| 136 | 112 | testNegationWrappingEval(@minValue(i16)); |
| 137 | 113 | } |
| 138 | 114 | fn testNegationWrappingEval(x: i16) { |
| ... | ... | @@ -141,9 +117,7 @@ fn testNegationWrappingEval(x: i16) { |
| 141 | 117 | assert(neg == -32768); |
| 142 | 118 | } |
| 143 | 119 | |
| 144 | fn shlWrapping() { | |
| 145 | @setFnTest(this); | |
| 146 | ||
| 120 | test "shlWrapping" { | |
| 147 | 121 | testShlWrappingEval(@maxValue(u16)); |
| 148 | 122 | } |
| 149 | 123 | fn testShlWrappingEval(x: u16) { |
| ... | ... | @@ -151,9 +125,7 @@ fn testShlWrappingEval(x: u16) { |
| 151 | 125 | assert(shifted == 65534); |
| 152 | 126 | } |
| 153 | 127 | |
| 154 | fn unsigned64BitDivision() { | |
| 155 | @setFnTest(this); | |
| 156 | ||
| 128 | test "unsigned64BitDivision" { | |
| 157 | 129 | const result = div(1152921504606846976, 34359738365); |
| 158 | 130 | assert(result.quotient == 33554432); |
| 159 | 131 | assert(result.remainder == 100663296); |
| ... | ... | @@ -169,9 +141,7 @@ const DivResult = struct { |
| 169 | 141 | remainder: u64, |
| 170 | 142 | }; |
| 171 | 143 | |
| 172 | fn binaryNot() { | |
| 173 | @setFnTest(this); | |
| 174 | ||
| 144 | test "binaryNot" { | |
| 175 | 145 | assert(comptime {~u16(0b1010101010101010) == 0b0101010101010101}); |
| 176 | 146 | assert(comptime {~u64(2147483647) == 18446744071562067968}); |
| 177 | 147 | testBinaryNot(0b1010101010101010); |
| ... | ... | @@ -181,9 +151,7 @@ fn testBinaryNot(x: u16) { |
| 181 | 151 | assert(~x == 0b0101010101010101); |
| 182 | 152 | } |
| 183 | 153 | |
| 184 | fn smallIntAddition() { | |
| 185 | @setFnTest(this); | |
| 186 | ||
| 154 | test "smallIntAddition" { | |
| 187 | 155 | var x: @intType(false, 2) = 0; |
| 188 | 156 | assert(x == 0); |
| 189 | 157 | |
| ... | ... | @@ -202,9 +170,7 @@ fn smallIntAddition() { |
| 202 | 170 | assert(result == 0); |
| 203 | 171 | } |
| 204 | 172 | |
| 205 | fn testFloatEquality() { | |
| 206 | @setFnTest(this); | |
| 207 | ||
| 173 | test "testFloatEquality" { | |
| 208 | 174 | const x: f64 = 0.012; |
| 209 | 175 | const y: f64 = x + 1.0; |
| 210 | 176 |
test/cases/misc.zig+48-131| ... | ... | @@ -5,23 +5,21 @@ const cstr = @import("std").cstr; |
| 5 | 5 | // normal comment |
| 6 | 6 | /// this is a documentation comment |
| 7 | 7 | /// doc comment line 2 |
| 8 | fn emptyFunctionWithComments() { | |
| 9 | @setFnTest(this); | |
| 8 | fn emptyFunctionWithComments() {} | |
| 9 | ||
| 10 | test "emptyFunctionWithComments" { | |
| 11 | emptyFunctionWithComments(); | |
| 10 | 12 | } |
| 11 | 13 | |
| 12 | 14 | export fn disabledExternFn() { |
| 13 | 15 | @setFnVisible(this, false); |
| 14 | 16 | } |
| 15 | 17 | |
| 16 | fn callDisabledExternFn() { | |
| 17 | @setFnTest(this); | |
| 18 | ||
| 18 | test "callDisabledExternFn" { | |
| 19 | 19 | disabledExternFn(); |
| 20 | 20 | } |
| 21 | 21 | |
| 22 | fn intTypeBuiltin() { | |
| 23 | @setFnTest(this); | |
| 24 | ||
| 22 | test "intTypeBuiltin" { | |
| 25 | 23 | assert(@intType(true, 8) == i8); |
| 26 | 24 | assert(@intType(true, 16) == i16); |
| 27 | 25 | assert(@intType(true, 32) == i32); |
| ... | ... | @@ -55,9 +53,7 @@ const u63 = @intType(false, 63); |
| 55 | 53 | const i1 = @intType(true, 1); |
| 56 | 54 | const i63 = @intType(true, 63); |
| 57 | 55 | |
| 58 | fn minValueAndMaxValue() { | |
| 59 | @setFnTest(this); | |
| 60 | ||
| 56 | test "minValueAndMaxValue" { | |
| 61 | 57 | assert(@maxValue(u1) == 1); |
| 62 | 58 | assert(@maxValue(u8) == 255); |
| 63 | 59 | assert(@maxValue(u16) == 65535); |
| ... | ... | @@ -86,9 +82,7 @@ fn minValueAndMaxValue() { |
| 86 | 82 | assert(@minValue(i64) == -9223372036854775808); |
| 87 | 83 | } |
| 88 | 84 | |
| 89 | fn maxValueType() { | |
| 90 | @setFnTest(this); | |
| 91 | ||
| 85 | test "maxValueType" { | |
| 92 | 86 | // If the type of @maxValue(i32) was i32 then this implicit cast to |
| 93 | 87 | // u32 would not work. But since the value is a number literal, |
| 94 | 88 | // it works fine. |
| ... | ... | @@ -96,8 +90,7 @@ fn maxValueType() { |
| 96 | 90 | assert(x == 2147483647); |
| 97 | 91 | } |
| 98 | 92 | |
| 99 | fn shortCircuit() { | |
| 100 | @setFnTest(this); | |
| 93 | test "shortCircuit" { | |
| 101 | 94 | testShortCircuit(false, true); |
| 102 | 95 | } |
| 103 | 96 | |
| ... | ... | @@ -128,18 +121,14 @@ fn testShortCircuit(f: bool, t: bool) { |
| 128 | 121 | assert(hit_4); |
| 129 | 122 | } |
| 130 | 123 | |
| 131 | fn truncate() { | |
| 132 | @setFnTest(this); | |
| 133 | ||
| 124 | test "truncate" { | |
| 134 | 125 | assert(testTruncate(0x10fd) == 0xfd); |
| 135 | 126 | } |
| 136 | 127 | fn testTruncate(x: u32) -> u8 { |
| 137 | 128 | @truncate(u8, x) |
| 138 | 129 | } |
| 139 | 130 | |
| 140 | fn assignToIfVarPtr() { | |
| 141 | @setFnTest(this); | |
| 142 | ||
| 131 | test "assignToIfVarPtr" { | |
| 143 | 132 | var maybe_bool: ?bool = true; |
| 144 | 133 | |
| 145 | 134 | if (const *b ?= maybe_bool) { |
| ... | ... | @@ -153,27 +142,21 @@ fn first4KeysOfHomeRow() -> []const u8 { |
| 153 | 142 | "aoeu" |
| 154 | 143 | } |
| 155 | 144 | |
| 156 | fn ReturnStringFromFunction() { | |
| 157 | @setFnTest(this); | |
| 158 | ||
| 145 | test "ReturnStringFromFunction" { | |
| 159 | 146 | assert(mem.eql(u8, first4KeysOfHomeRow(), "aoeu")); |
| 160 | 147 | } |
| 161 | 148 | |
| 162 | 149 | const g1 : i32 = 1233 + 1; |
| 163 | 150 | var g2 : i32 = 0; |
| 164 | 151 | |
| 165 | fn globalVariables() { | |
| 166 | @setFnTest(this); | |
| 167 | ||
| 152 | test "globalVariables" { | |
| 168 | 153 | assert(g2 == 0); |
| 169 | 154 | g2 = g1; |
| 170 | 155 | assert(g2 == 1234); |
| 171 | 156 | } |
| 172 | 157 | |
| 173 | 158 | |
| 174 | fn memcpyAndMemsetIntrinsics() { | |
| 175 | @setFnTest(this); | |
| 176 | ||
| 159 | test "memcpyAndMemsetIntrinsics" { | |
| 177 | 160 | var foo : [20]u8 = undefined; |
| 178 | 161 | var bar : [20]u8 = undefined; |
| 179 | 162 | |
| ... | ... | @@ -183,16 +166,12 @@ fn memcpyAndMemsetIntrinsics() { |
| 183 | 166 | if (bar[11] != 'A') @unreachable(); |
| 184 | 167 | } |
| 185 | 168 | |
| 186 | fn builtinStaticEval() { | |
| 187 | @setFnTest(this); | |
| 188 | ||
| 169 | test "builtinStaticEval" { | |
| 189 | 170 | const x : i32 = comptime {1 + 2 + 3}; |
| 190 | 171 | assert(x == comptime 6); |
| 191 | 172 | } |
| 192 | 173 | |
| 193 | fn slicing() { | |
| 194 | @setFnTest(this); | |
| 195 | ||
| 174 | test "slicing" { | |
| 196 | 175 | var array : [20]i32 = undefined; |
| 197 | 176 | |
| 198 | 177 | array[5] = 1234; |
| ... | ... | @@ -209,9 +188,7 @@ fn slicing() { |
| 209 | 188 | } |
| 210 | 189 | |
| 211 | 190 | |
| 212 | fn constantEqualFunctionPointers() { | |
| 213 | @setFnTest(this); | |
| 214 | ||
| 191 | test "constantEqualFunctionPointers" { | |
| 215 | 192 | const alias = emptyFn; |
| 216 | 193 | assert(comptime {emptyFn == alias}); |
| 217 | 194 | } |
| ... | ... | @@ -219,27 +196,19 @@ fn constantEqualFunctionPointers() { |
| 219 | 196 | fn emptyFn() {} |
| 220 | 197 | |
| 221 | 198 | |
| 222 | fn hexEscape() { | |
| 223 | @setFnTest(this); | |
| 224 | ||
| 199 | test "hexEscape" { | |
| 225 | 200 | assert(mem.eql(u8, "\x68\x65\x6c\x6c\x6f", "hello")); |
| 226 | 201 | } |
| 227 | 202 | |
| 228 | fn stringConcatenation() { | |
| 229 | @setFnTest(this); | |
| 230 | ||
| 203 | test "stringConcatenation" { | |
| 231 | 204 | assert(mem.eql(u8, "OK" ++ " IT " ++ "WORKED", "OK IT WORKED")); |
| 232 | 205 | } |
| 233 | 206 | |
| 234 | fn arrayMultOperator() { | |
| 235 | @setFnTest(this); | |
| 236 | ||
| 207 | test "arrayMultOperator" { | |
| 237 | 208 | assert(mem.eql(u8, "ab" ** 5, "ababababab")); |
| 238 | 209 | } |
| 239 | 210 | |
| 240 | fn stringEscapes() { | |
| 241 | @setFnTest(this); | |
| 242 | ||
| 211 | test "stringEscapes" { | |
| 243 | 212 | assert(mem.eql(u8, "\"", "\x22")); |
| 244 | 213 | assert(mem.eql(u8, "\'", "\x27")); |
| 245 | 214 | assert(mem.eql(u8, "\n", "\x0a")); |
| ... | ... | @@ -249,9 +218,7 @@ fn stringEscapes() { |
| 249 | 218 | assert(mem.eql(u8, "\u1234\u0069", "\xe1\x88\xb4\x69")); |
| 250 | 219 | } |
| 251 | 220 | |
| 252 | fn multilineString() { | |
| 253 | @setFnTest(this); | |
| 254 | ||
| 221 | test "multilineString" { | |
| 255 | 222 | const s1 = |
| 256 | 223 | \\one |
| 257 | 224 | \\two) |
| ... | ... | @@ -261,9 +228,7 @@ fn multilineString() { |
| 261 | 228 | assert(mem.eql(u8, s1, s2)); |
| 262 | 229 | } |
| 263 | 230 | |
| 264 | fn multilineCString() { | |
| 265 | @setFnTest(this); | |
| 266 | ||
| 231 | test "multilineCString" { | |
| 267 | 232 | const s1 = |
| 268 | 233 | c\\one |
| 269 | 234 | c\\two) |
| ... | ... | @@ -274,9 +239,7 @@ fn multilineCString() { |
| 274 | 239 | } |
| 275 | 240 | |
| 276 | 241 | |
| 277 | fn typeEquality() { | |
| 278 | @setFnTest(this); | |
| 279 | ||
| 242 | test "typeEquality" { | |
| 280 | 243 | assert(&const u8 != &u8); |
| 281 | 244 | } |
| 282 | 245 | |
| ... | ... | @@ -284,22 +247,17 @@ fn typeEquality() { |
| 284 | 247 | const global_a: i32 = 1234; |
| 285 | 248 | const global_b: &const i32 = &global_a; |
| 286 | 249 | const global_c: &const f32 = (&const f32)(global_b); |
| 287 | fn compileTimeGlobalReinterpret() { | |
| 288 | @setFnTest(this); | |
| 250 | test "compileTimeGlobalReinterpret" { | |
| 289 | 251 | const d = (&const i32)(global_c); |
| 290 | 252 | assert(*d == 1234); |
| 291 | 253 | } |
| 292 | 254 | |
| 293 | fn explicitCastMaybePointers() { | |
| 294 | @setFnTest(this); | |
| 295 | ||
| 255 | test "explicitCastMaybePointers" { | |
| 296 | 256 | const a: ?&i32 = undefined; |
| 297 | 257 | const b: ?&f32 = (?&f32)(a); |
| 298 | 258 | } |
| 299 | 259 | |
| 300 | fn genericMallocFree() { | |
| 301 | @setFnTest(this); | |
| 302 | ||
| 260 | test "genericMallocFree" { | |
| 303 | 261 | const a = %%memAlloc(u8, 10); |
| 304 | 262 | memFree(u8, a); |
| 305 | 263 | } |
| ... | ... | @@ -310,9 +268,7 @@ fn memAlloc(comptime T: type, n: usize) -> %[]T { |
| 310 | 268 | fn memFree(comptime T: type, memory: []T) { } |
| 311 | 269 | |
| 312 | 270 | |
| 313 | fn castUndefined() { | |
| 314 | @setFnTest(this); | |
| 315 | ||
| 271 | test "castUndefined" { | |
| 316 | 272 | const array: [100]u8 = undefined; |
| 317 | 273 | const slice = ([]const u8)(array); |
| 318 | 274 | testCastUndefined(slice); |
| ... | ... | @@ -320,9 +276,7 @@ fn castUndefined() { |
| 320 | 276 | fn testCastUndefined(x: []const u8) {} |
| 321 | 277 | |
| 322 | 278 | |
| 323 | fn castSmallUnsignedToLargerSigned() { | |
| 324 | @setFnTest(this); | |
| 325 | ||
| 279 | test "castSmallUnsignedToLargerSigned" { | |
| 326 | 280 | assert(castSmallUnsignedToLargerSigned1(200) == i16(200)); |
| 327 | 281 | assert(castSmallUnsignedToLargerSigned2(9999) == i64(9999)); |
| 328 | 282 | } |
| ... | ... | @@ -330,9 +284,7 @@ fn castSmallUnsignedToLargerSigned1(x: u8) -> i16 { x } |
| 330 | 284 | fn castSmallUnsignedToLargerSigned2(x: u16) -> i64 { x } |
| 331 | 285 | |
| 332 | 286 | |
| 333 | fn implicitCastAfterUnreachable() { | |
| 334 | @setFnTest(this); | |
| 335 | ||
| 287 | test "implicitCastAfterUnreachable" { | |
| 336 | 288 | assert(outer() == 1234); |
| 337 | 289 | } |
| 338 | 290 | fn inner() -> i32 { 1234 } |
| ... | ... | @@ -341,9 +293,7 @@ fn outer() -> i64 { |
| 341 | 293 | } |
| 342 | 294 | |
| 343 | 295 | |
| 344 | fn pointerDereferencing() { | |
| 345 | @setFnTest(this); | |
| 346 | ||
| 296 | test "pointerDereferencing" { | |
| 347 | 297 | var x = i32(3); |
| 348 | 298 | const y = &x; |
| 349 | 299 | |
| ... | ... | @@ -353,9 +303,7 @@ fn pointerDereferencing() { |
| 353 | 303 | assert(*y == 4); |
| 354 | 304 | } |
| 355 | 305 | |
| 356 | fn callResultOfIfElseExpression() { | |
| 357 | @setFnTest(this); | |
| 358 | ||
| 306 | test "callResultOfIfElseExpression" { | |
| 359 | 307 | assert(mem.eql(u8, f2(true), "a")); |
| 360 | 308 | assert(mem.eql(u8, f2(false), "b")); |
| 361 | 309 | } |
| ... | ... | @@ -366,9 +314,7 @@ fn fA() -> []const u8 { "a" } |
| 366 | 314 | fn fB() -> []const u8 { "b" } |
| 367 | 315 | |
| 368 | 316 | |
| 369 | fn constExpressionEvalHandlingOfVariables() { | |
| 370 | @setFnTest(this); | |
| 371 | ||
| 317 | test "constExpressionEvalHandlingOfVariables" { | |
| 372 | 318 | var x = true; |
| 373 | 319 | while (x) { |
| 374 | 320 | x = false; |
| ... | ... | @@ -377,9 +323,7 @@ fn constExpressionEvalHandlingOfVariables() { |
| 377 | 323 | |
| 378 | 324 | |
| 379 | 325 | |
| 380 | fn constantEnumInitializationWithDifferingSizes() { | |
| 381 | @setFnTest(this); | |
| 382 | ||
| 326 | test "constantEnumInitializationWithDifferingSizes" { | |
| 383 | 327 | test3_1(test3_foo); |
| 384 | 328 | test3_2(test3_bar); |
| 385 | 329 | } |
| ... | ... | @@ -413,18 +357,14 @@ fn test3_2(f: Test3Foo) { |
| 413 | 357 | } |
| 414 | 358 | |
| 415 | 359 | |
| 416 | fn characterLiterals() { | |
| 417 | @setFnTest(this); | |
| 418 | ||
| 360 | test "characterLiterals" { | |
| 419 | 361 | assert('\'' == single_quote); |
| 420 | 362 | } |
| 421 | 363 | const single_quote = '\''; |
| 422 | 364 | |
| 423 | 365 | |
| 424 | 366 | |
| 425 | fn takeAddressOfParameter() { | |
| 426 | @setFnTest(this); | |
| 427 | ||
| 367 | test "takeAddressOfParameter" { | |
| 428 | 368 | testTakeAddressOfParameter(12.34); |
| 429 | 369 | } |
| 430 | 370 | fn testTakeAddressOfParameter(f: f32) { |
| ... | ... | @@ -433,9 +373,7 @@ fn testTakeAddressOfParameter(f: f32) { |
| 433 | 373 | } |
| 434 | 374 | |
| 435 | 375 | |
| 436 | fn intToPtrCast() { | |
| 437 | @setFnTest(this); | |
| 438 | ||
| 376 | test "intToPtrCast" { | |
| 439 | 377 | const x = isize(13); |
| 440 | 378 | const y = (&u8)(x); |
| 441 | 379 | const z = usize(y); |
| ... | ... | @@ -443,9 +381,7 @@ fn intToPtrCast() { |
| 443 | 381 | } |
| 444 | 382 | |
| 445 | 383 | |
| 446 | fn pointerComparison() { | |
| 447 | @setFnTest(this); | |
| 448 | ||
| 384 | test "pointerComparison" { | |
| 449 | 385 | const a = ([]const u8)("a"); |
| 450 | 386 | const b = &a; |
| 451 | 387 | assert(ptrEql(b, b)); |
| ... | ... | @@ -455,9 +391,7 @@ fn ptrEql(a: &const []const u8, b: &const []const u8) -> bool { |
| 455 | 391 | } |
| 456 | 392 | |
| 457 | 393 | |
| 458 | fn cStringConcatenation() { | |
| 459 | @setFnTest(this); | |
| 460 | ||
| 394 | test "cStringConcatenation" { | |
| 461 | 395 | const a = c"OK" ++ c" IT " ++ c"WORKED"; |
| 462 | 396 | const b = c"OK IT WORKED"; |
| 463 | 397 | |
| ... | ... | @@ -470,9 +404,7 @@ fn cStringConcatenation() { |
| 470 | 404 | assert(b[len] == 0); |
| 471 | 405 | } |
| 472 | 406 | |
| 473 | fn castSliceToU8Slice() { | |
| 474 | @setFnTest(this); | |
| 475 | ||
| 407 | test "castSliceToU8Slice" { | |
| 476 | 408 | assert(@sizeOf(i32) == 4); |
| 477 | 409 | var big_thing_array = []i32{1, 2, 3, 4}; |
| 478 | 410 | const big_thing_slice: []i32 = big_thing_array[0...]; |
| ... | ... | @@ -492,9 +424,7 @@ fn castSliceToU8Slice() { |
| 492 | 424 | assert(bytes[11] == @maxValue(u8)); |
| 493 | 425 | } |
| 494 | 426 | |
| 495 | fn pointerToVoidReturnType() { | |
| 496 | @setFnTest(this); | |
| 497 | ||
| 427 | test "pointerToVoidReturnType" { | |
| 498 | 428 | %%testPointerToVoidReturnType(); |
| 499 | 429 | } |
| 500 | 430 | fn testPointerToVoidReturnType() -> %void { |
| ... | ... | @@ -507,17 +437,14 @@ fn testPointerToVoidReturnType2() -> &const void { |
| 507 | 437 | } |
| 508 | 438 | |
| 509 | 439 | |
| 510 | fn nonConstPtrToAliasedType() { | |
| 511 | @setFnTest(this); | |
| 440 | test "nonConstPtrToAliasedType" { | |
| 512 | 441 | const int = i32; |
| 513 | 442 | assert(?&int == ?&i32); |
| 514 | 443 | } |
| 515 | 444 | |
| 516 | 445 | |
| 517 | 446 | |
| 518 | fn array2DConstDoublePtr() { | |
| 519 | @setFnTest(this); | |
| 520 | ||
| 447 | test "array2DConstDoublePtr" { | |
| 521 | 448 | const rect_2d_vertexes = [][1]f32 { |
| 522 | 449 | []f32{1.0}, |
| 523 | 450 | []f32{2.0}, |
| ... | ... | @@ -530,9 +457,7 @@ fn testArray2DConstDoublePtr(ptr: &const f32) { |
| 530 | 457 | assert(ptr[1] == 2.0); |
| 531 | 458 | } |
| 532 | 459 | |
| 533 | fn isInteger() { | |
| 534 | @setFnTest(this); | |
| 535 | ||
| 460 | test "isInteger" { | |
| 536 | 461 | comptime { |
| 537 | 462 | assert(@isInteger(i8)); |
| 538 | 463 | assert(@isInteger(u8)); |
| ... | ... | @@ -545,9 +470,7 @@ fn isInteger() { |
| 545 | 470 | } |
| 546 | 471 | } |
| 547 | 472 | |
| 548 | fn isFloat() { | |
| 549 | @setFnTest(this); | |
| 550 | ||
| 473 | test "isFloat" { | |
| 551 | 474 | comptime { |
| 552 | 475 | assert(!@isFloat(i8)); |
| 553 | 476 | assert(!@isFloat(u8)); |
| ... | ... | @@ -560,9 +483,7 @@ fn isFloat() { |
| 560 | 483 | } |
| 561 | 484 | } |
| 562 | 485 | |
| 563 | fn canImplicitCast() { | |
| 564 | @setFnTest(this); | |
| 565 | ||
| 486 | test "canImplicitCast" { | |
| 566 | 487 | comptime { |
| 567 | 488 | assert(@canImplicitCast(i64, i32(3))); |
| 568 | 489 | assert(!@canImplicitCast(i32, f32(1.234))); |
| ... | ... | @@ -570,18 +491,14 @@ fn canImplicitCast() { |
| 570 | 491 | } |
| 571 | 492 | } |
| 572 | 493 | |
| 573 | fn typeName() { | |
| 574 | @setFnTest(this); | |
| 575 | ||
| 494 | test "typeName" { | |
| 576 | 495 | comptime { |
| 577 | 496 | assert(mem.eql(u8, @typeName(i64), "i64")); |
| 578 | 497 | assert(mem.eql(u8, @typeName(&usize), "&usize")); |
| 579 | 498 | } |
| 580 | 499 | } |
| 581 | 500 | |
| 582 | fn volatileLoadAndStore() { | |
| 583 | @setFnTest(this); | |
| 584 | ||
| 501 | test "volatileLoadAndStore" { | |
| 585 | 502 | var number: i32 = 1234; |
| 586 | 503 | const ptr = &volatile number; |
| 587 | 504 | *ptr += 1; |
test/cases/namespace_depends_on_compile_var/index.zig+1-3| ... | ... | @@ -1,8 +1,6 @@ |
| 1 | 1 | const assert = @import("std").debug.assert; |
| 2 | 2 | |
| 3 | fn namespaceDependsOnCompileVar() { | |
| 4 | @setFnTest(this); | |
| 5 | ||
| 3 | test "namespaceDependsOnCompileVar" { | |
| 6 | 4 | if (some_namespace.a_bool) { |
| 7 | 5 | assert(some_namespace.a_bool); |
| 8 | 6 | } else { |
test/cases/null.zig+8-24| ... | ... | @@ -1,8 +1,6 @@ |
| 1 | 1 | const assert = @import("std").debug.assert; |
| 2 | 2 | |
| 3 | fn nullableType() { | |
| 4 | @setFnTest(this); | |
| 5 | ||
| 3 | test "nullableType" { | |
| 6 | 4 | const x : ?bool = @generatedCode(true); |
| 7 | 5 | |
| 8 | 6 | if (const y ?= x) { |
| ... | ... | @@ -28,9 +26,7 @@ fn nullableType() { |
| 28 | 26 | assert(num == 13); |
| 29 | 27 | } |
| 30 | 28 | |
| 31 | fn assignToIfVarPtr() { | |
| 32 | @setFnTest(this); | |
| 33 | ||
| 29 | test "assignToIfVarPtr" { | |
| 34 | 30 | var maybe_bool: ?bool = true; |
| 35 | 31 | |
| 36 | 32 | if (const *b ?= maybe_bool) { |
| ... | ... | @@ -40,17 +36,13 @@ fn assignToIfVarPtr() { |
| 40 | 36 | assert(??maybe_bool == false); |
| 41 | 37 | } |
| 42 | 38 | |
| 43 | fn rhsMaybeUnwrapReturn() { | |
| 44 | @setFnTest(this); | |
| 45 | ||
| 39 | test "rhsMaybeUnwrapReturn" { | |
| 46 | 40 | const x: ?bool = @generatedCode(true); |
| 47 | 41 | const y = x ?? return; |
| 48 | 42 | } |
| 49 | 43 | |
| 50 | 44 | |
| 51 | fn maybeReturn() { | |
| 52 | @setFnTest(this); | |
| 53 | ||
| 45 | test "maybeReturn" { | |
| 54 | 46 | maybeReturnImpl(); |
| 55 | 47 | comptime maybeReturnImpl(); |
| 56 | 48 | } |
| ... | ... | @@ -67,9 +59,7 @@ fn foo(x: ?i32) -> ?bool { |
| 67 | 59 | } |
| 68 | 60 | |
| 69 | 61 | |
| 70 | fn ifVarMaybePointer() { | |
| 71 | @setFnTest(this); | |
| 72 | ||
| 62 | test "ifVarMaybePointer" { | |
| 73 | 63 | assert(shouldBeAPlus1(Particle {.a = 14, .b = 1, .c = 1, .d = 1}) == 15); |
| 74 | 64 | } |
| 75 | 65 | fn shouldBeAPlus1(p: Particle) -> u64 { |
| ... | ... | @@ -90,9 +80,7 @@ const Particle = struct { |
| 90 | 80 | }; |
| 91 | 81 | |
| 92 | 82 | |
| 93 | fn nullLiteralOutsideFunction() { | |
| 94 | @setFnTest(this); | |
| 95 | ||
| 83 | test "nullLiteralOutsideFunction" { | |
| 96 | 84 | const is_null = here_is_a_null_literal.context == null; |
| 97 | 85 | assert(is_null); |
| 98 | 86 | |
| ... | ... | @@ -107,9 +95,7 @@ const here_is_a_null_literal = SillyStruct { |
| 107 | 95 | }; |
| 108 | 96 | |
| 109 | 97 | |
| 110 | fn testNullRuntime() { | |
| 111 | @setFnTest(this); | |
| 112 | ||
| 98 | test "testNullRuntime" { | |
| 113 | 99 | testTestNullRuntime(null); |
| 114 | 100 | } |
| 115 | 101 | fn testTestNullRuntime(x: ?i32) { |
| ... | ... | @@ -117,9 +103,7 @@ fn testTestNullRuntime(x: ?i32) { |
| 117 | 103 | assert(!(x != null)); |
| 118 | 104 | } |
| 119 | 105 | |
| 120 | fn nullableVoid() { | |
| 121 | @setFnTest(this); | |
| 122 | ||
| 106 | test "nullableVoid" { | |
| 123 | 107 | nullableVoidImpl(); |
| 124 | 108 | comptime nullableVoidImpl(); |
| 125 | 109 | } |
test/cases/pub_enum/index.zig+2-6| ... | ... | @@ -1,17 +1,13 @@ |
| 1 | 1 | const other = @import("cases/pub_enum/other.zig"); |
| 2 | 2 | const assert = @import("std").debug.assert; |
| 3 | 3 | |
| 4 | fn pubEnum() { | |
| 5 | @setFnTest(this); | |
| 6 | ||
| 4 | test "pubEnum" { | |
| 7 | 5 | pubEnumTest(other.APubEnum.Two); |
| 8 | 6 | } |
| 9 | 7 | fn pubEnumTest(foo: other.APubEnum) { |
| 10 | 8 | assert(foo == other.APubEnum.Two); |
| 11 | 9 | } |
| 12 | 10 | |
| 13 | fn castWithImportedSymbol() { | |
| 14 | @setFnTest(this); | |
| 15 | ||
| 11 | test "castWithImportedSymbol" { | |
| 16 | 12 | assert(other.size_t(42) == 42); |
| 17 | 13 | } |
test/cases/sizeof_and_typeof.zig+1-3| ... | ... | @@ -1,8 +1,6 @@ |
| 1 | 1 | const assert = @import("std").debug.assert; |
| 2 | 2 | |
| 3 | fn sizeofAndTypeOf() { | |
| 4 | @setFnTest(this); | |
| 5 | ||
| 3 | test "sizeofAndTypeOf" { | |
| 6 | 4 | const y: @typeOf(x) = 120; |
| 7 | 5 | assert(@sizeOf(@typeOf(y)) == 2); |
| 8 | 6 | } |
test/cases/struct.zig+22-56| ... | ... | @@ -5,27 +5,25 @@ const StructWithNoFields = struct { |
| 5 | 5 | }; |
| 6 | 6 | const empty_global_instance = StructWithNoFields {}; |
| 7 | 7 | |
| 8 | fn callStructStaticMethod() { | |
| 9 | @setFnTest(this); | |
| 8 | test "callStructStaticMethod" { | |
| 10 | 9 | const result = StructWithNoFields.add(3, 4); |
| 11 | 10 | assert(result == 7); |
| 12 | 11 | } |
| 13 | 12 | |
| 13 | test "returnEmptyStructInstance" { | |
| 14 | _ = returnEmptyStructInstance(); | |
| 15 | } | |
| 14 | 16 | fn returnEmptyStructInstance() -> StructWithNoFields { |
| 15 | @setFnTest(this); | |
| 16 | 17 | return empty_global_instance; |
| 17 | 18 | } |
| 18 | 19 | |
| 19 | 20 | const should_be_11 = StructWithNoFields.add(5, 6); |
| 20 | 21 | |
| 21 | fn invokeStaticMethodInGlobalScope() { | |
| 22 | @setFnTest(this); | |
| 22 | test "invokeStaticMethodInGlobalScope" { | |
| 23 | 23 | assert(should_be_11 == 11); |
| 24 | 24 | } |
| 25 | 25 | |
| 26 | fn voidStructFields() { | |
| 27 | @setFnTest(this); | |
| 28 | ||
| 26 | test "voidStructFields" { | |
| 29 | 27 | const foo = VoidStructFieldsFoo { |
| 30 | 28 | .a = void{}, |
| 31 | 29 | .b = 1, |
| ... | ... | @@ -41,9 +39,7 @@ const VoidStructFieldsFoo = struct { |
| 41 | 39 | }; |
| 42 | 40 | |
| 43 | 41 | |
| 44 | pub fn structs() { | |
| 45 | @setFnTest(this); | |
| 46 | ||
| 42 | test "fn" { | |
| 47 | 43 | var foo: StructFoo = undefined; |
| 48 | 44 | @memset((&u8)(&foo), 0, @sizeOf(StructFoo)); |
| 49 | 45 | foo.a += 1; |
| ... | ... | @@ -74,9 +70,7 @@ const Val = struct { |
| 74 | 70 | x: i32, |
| 75 | 71 | }; |
| 76 | 72 | |
| 77 | fn structPointToSelf() { | |
| 78 | @setFnTest(this); | |
| 79 | ||
| 73 | test "structPointToSelf" { | |
| 80 | 74 | var root : Node = undefined; |
| 81 | 75 | root.val.x = 1; |
| 82 | 76 | |
| ... | ... | @@ -89,9 +83,7 @@ fn structPointToSelf() { |
| 89 | 83 | assert(node.next.next.next.val.x == 1); |
| 90 | 84 | } |
| 91 | 85 | |
| 92 | fn structByvalAssign() { | |
| 93 | @setFnTest(this); | |
| 94 | ||
| 86 | test "structByvalAssign" { | |
| 95 | 87 | var foo1 : StructFoo = undefined; |
| 96 | 88 | var foo2 : StructFoo = undefined; |
| 97 | 89 | |
| ... | ... | @@ -108,9 +100,7 @@ fn structInitializer() { |
| 108 | 100 | } |
| 109 | 101 | |
| 110 | 102 | |
| 111 | fn fnCallOfStructField() { | |
| 112 | @setFnTest(this); | |
| 113 | ||
| 103 | test "fnCallOfStructField" { | |
| 114 | 104 | assert(callStructField(Foo {.ptr = aFunc,}) == 13); |
| 115 | 105 | } |
| 116 | 106 | |
| ... | ... | @@ -125,9 +115,7 @@ fn callStructField(foo: Foo) -> i32 { |
| 125 | 115 | } |
| 126 | 116 | |
| 127 | 117 | |
| 128 | fn storeMemberFunctionInVariable() { | |
| 129 | @setFnTest(this); | |
| 130 | ||
| 118 | test "storeMemberFunctionInVariable" { | |
| 131 | 119 | const instance = MemberFnTestFoo { .x = 1234, }; |
| 132 | 120 | const memberFn = MemberFnTestFoo.member; |
| 133 | 121 | const result = memberFn(instance); |
| ... | ... | @@ -139,17 +127,13 @@ const MemberFnTestFoo = struct { |
| 139 | 127 | }; |
| 140 | 128 | |
| 141 | 129 | |
| 142 | fn callMemberFunctionDirectly() { | |
| 143 | @setFnTest(this); | |
| 144 | ||
| 130 | test "callMemberFunctionDirectly" { | |
| 145 | 131 | const instance = MemberFnTestFoo { .x = 1234, }; |
| 146 | 132 | const result = MemberFnTestFoo.member(instance); |
| 147 | 133 | assert(result == 1234); |
| 148 | 134 | } |
| 149 | 135 | |
| 150 | fn memberFunctions() { | |
| 151 | @setFnTest(this); | |
| 152 | ||
| 136 | test "memberFunctions" { | |
| 153 | 137 | const r = MemberFnRand {.seed = 1234}; |
| 154 | 138 | assert(r.getSeed() == 1234); |
| 155 | 139 | } |
| ... | ... | @@ -160,9 +144,7 @@ const MemberFnRand = struct { |
| 160 | 144 | } |
| 161 | 145 | }; |
| 162 | 146 | |
| 163 | fn returnStructByvalFromFunction() { | |
| 164 | @setFnTest(this); | |
| 165 | ||
| 147 | test "returnStructByvalFromFunction" { | |
| 166 | 148 | const bar = makeBar(1234, 5678); |
| 167 | 149 | assert(bar.y == 5678); |
| 168 | 150 | } |
| ... | ... | @@ -177,9 +159,7 @@ fn makeBar(x: i32, y: i32) -> Bar { |
| 177 | 159 | } |
| 178 | 160 | } |
| 179 | 161 | |
| 180 | fn emptyStructMethodCall() { | |
| 181 | @setFnTest(this); | |
| 182 | ||
| 162 | test "emptyStructMethodCall" { | |
| 183 | 163 | const es = EmptyStruct{}; |
| 184 | 164 | assert(es.method() == 1234); |
| 185 | 165 | } |
| ... | ... | @@ -190,9 +170,7 @@ const EmptyStruct = struct { |
| 190 | 170 | }; |
| 191 | 171 | |
| 192 | 172 | |
| 193 | fn returnEmptyStructFromFn() { | |
| 194 | @setFnTest(this); | |
| 195 | ||
| 173 | test "returnEmptyStructFromFn" { | |
| 196 | 174 | _ = testReturnEmptyStructFromFn(); |
| 197 | 175 | } |
| 198 | 176 | const EmptyStruct2 = struct {}; |
| ... | ... | @@ -200,9 +178,7 @@ fn testReturnEmptyStructFromFn() -> EmptyStruct2 { |
| 200 | 178 | EmptyStruct2 {} |
| 201 | 179 | } |
| 202 | 180 | |
| 203 | fn passSliceOfEmptyStructToFn() { | |
| 204 | @setFnTest(this); | |
| 205 | ||
| 181 | test "passSliceOfEmptyStructToFn" { | |
| 206 | 182 | assert(testPassSliceOfEmptyStructToFn([]EmptyStruct2{ EmptyStruct2{} }) == 1); |
| 207 | 183 | } |
| 208 | 184 | fn testPassSliceOfEmptyStructToFn(slice: []const EmptyStruct2) -> usize { |
| ... | ... | @@ -214,9 +190,7 @@ const APackedStruct = packed struct { |
| 214 | 190 | y: u8, |
| 215 | 191 | }; |
| 216 | 192 | |
| 217 | fn packedStruct() { | |
| 218 | @setFnTest(this); | |
| 219 | ||
| 193 | test "packedStruct" { | |
| 220 | 194 | var foo = APackedStruct { |
| 221 | 195 | .x = 1, |
| 222 | 196 | .y = 2, |
| ... | ... | @@ -242,9 +216,7 @@ const bit_field_1 = BitField1 { |
| 242 | 216 | .c = 3, |
| 243 | 217 | }; |
| 244 | 218 | |
| 245 | fn bitFieldAccess() { | |
| 246 | @setFnTest(this); | |
| 247 | ||
| 219 | test "bitFieldAccess" { | |
| 248 | 220 | var data = bit_field_1; |
| 249 | 221 | assert(getA(&data) == 1); |
| 250 | 222 | assert(getB(&data) == 2); |
| ... | ... | @@ -282,9 +254,7 @@ const Foo96Bits = packed struct { |
| 282 | 254 | d: u24, |
| 283 | 255 | }; |
| 284 | 256 | |
| 285 | fn packedStruct24Bits() { | |
| 286 | @setFnTest(this); | |
| 287 | ||
| 257 | test "packedStruct24Bits" { | |
| 288 | 258 | comptime { |
| 289 | 259 | assert(@sizeOf(Foo24Bits) == 3); |
| 290 | 260 | assert(@sizeOf(Foo96Bits) == 12); |
| ... | ... | @@ -327,9 +297,7 @@ const FooArray24Bits = packed struct { |
| 327 | 297 | c: u16, |
| 328 | 298 | }; |
| 329 | 299 | |
| 330 | fn packedArray24Bits() { | |
| 331 | @setFnTest(this); | |
| 332 | ||
| 300 | test "packedArray24Bits" { | |
| 333 | 301 | comptime { |
| 334 | 302 | assert(@sizeOf([9]Foo24Bits) == 9 * 3); |
| 335 | 303 | assert(@sizeOf(FooArray24Bits) == 2 + 2 * 3 + 2); |
| ... | ... | @@ -379,9 +347,7 @@ const FooArrayOfAligned = packed struct { |
| 379 | 347 | a: [2]FooStructAligned, |
| 380 | 348 | }; |
| 381 | 349 | |
| 382 | fn alignedArrayOfPackedStruct() { | |
| 383 | @setFnTest(this); | |
| 384 | ||
| 350 | test "alignedArrayOfPackedStruct" { | |
| 385 | 351 | comptime { |
| 386 | 352 | assert(@sizeOf(FooStructAligned) == 2); |
| 387 | 353 | assert(@sizeOf(FooArrayOfAligned) == 2 * 2); |
test/cases/struct_contains_slice_of_itself.zig+1-3| ... | ... | @@ -5,9 +5,7 @@ const Node = struct { |
| 5 | 5 | children: []Node, |
| 6 | 6 | }; |
| 7 | 7 | |
| 8 | fn structContainsSliceOfItself() { | |
| 9 | @setFnTest(this); | |
| 10 | ||
| 8 | test "structContainsSliceOfItself" { | |
| 11 | 9 | var nodes = []Node { |
| 12 | 10 | Node { |
| 13 | 11 | .payload = 1, |
test/cases/switch.zig+8-24| ... | ... | @@ -1,8 +1,6 @@ |
| 1 | 1 | const assert = @import("std").debug.assert; |
| 2 | 2 | |
| 3 | fn switchWithNumbers() { | |
| 4 | @setFnTest(this); | |
| 5 | ||
| 3 | test "switchWithNumbers" { | |
| 6 | 4 | testSwitchWithNumbers(13); |
| 7 | 5 | } |
| 8 | 6 | |
| ... | ... | @@ -15,9 +13,7 @@ fn testSwitchWithNumbers(x: u32) { |
| 15 | 13 | assert(result); |
| 16 | 14 | } |
| 17 | 15 | |
| 18 | fn switchWithAllRanges() { | |
| 19 | @setFnTest(this); | |
| 20 | ||
| 16 | test "switchWithAllRanges" { | |
| 21 | 17 | assert(testSwitchWithAllRanges(50, 3) == 1); |
| 22 | 18 | assert(testSwitchWithAllRanges(101, 0) == 2); |
| 23 | 19 | assert(testSwitchWithAllRanges(300, 5) == 3); |
| ... | ... | @@ -33,9 +29,7 @@ fn testSwitchWithAllRanges(x: u32, y: u32) -> u32 { |
| 33 | 29 | } |
| 34 | 30 | } |
| 35 | 31 | |
| 36 | fn implicitComptimeSwitch() { | |
| 37 | @setFnTest(this); | |
| 38 | ||
| 32 | test "implicitComptimeSwitch" { | |
| 39 | 33 | const x = 3 + 4; |
| 40 | 34 | const result = switch (x) { |
| 41 | 35 | 3 => 10, |
| ... | ... | @@ -50,9 +44,7 @@ fn implicitComptimeSwitch() { |
| 50 | 44 | } |
| 51 | 45 | } |
| 52 | 46 | |
| 53 | fn switchOnEnum() { | |
| 54 | @setFnTest(this); | |
| 55 | ||
| 47 | test "switchOnEnum" { | |
| 56 | 48 | const fruit = Fruit.Orange; |
| 57 | 49 | nonConstSwitchOnEnum(fruit); |
| 58 | 50 | } |
| ... | ... | @@ -70,9 +62,7 @@ fn nonConstSwitchOnEnum(fruit: Fruit) { |
| 70 | 62 | } |
| 71 | 63 | |
| 72 | 64 | |
| 73 | fn switchStatement() { | |
| 74 | @setFnTest(this); | |
| 75 | ||
| 65 | test "switchStatement" { | |
| 76 | 66 | nonConstSwitch(SwitchStatmentFoo.C); |
| 77 | 67 | } |
| 78 | 68 | fn nonConstSwitch(foo: SwitchStatmentFoo) { |
| ... | ... | @@ -92,9 +82,7 @@ const SwitchStatmentFoo = enum { |
| 92 | 82 | }; |
| 93 | 83 | |
| 94 | 84 | |
| 95 | fn switchProngWithVar() { | |
| 96 | @setFnTest(this); | |
| 97 | ||
| 85 | test "switchProngWithVar" { | |
| 98 | 86 | switchProngWithVarFn(SwitchProngWithVarEnum.One {13}); |
| 99 | 87 | switchProngWithVarFn(SwitchProngWithVarEnum.Two {13.0}); |
| 100 | 88 | switchProngWithVarFn(SwitchProngWithVarEnum.Meh); |
| ... | ... | @@ -119,9 +107,7 @@ fn switchProngWithVarFn(a: SwitchProngWithVarEnum) { |
| 119 | 107 | } |
| 120 | 108 | |
| 121 | 109 | |
| 122 | fn switchWithMultipleExpressions() { | |
| 123 | @setFnTest(this); | |
| 124 | ||
| 110 | test "switchWithMultipleExpressions" { | |
| 125 | 111 | const x = switch (returnsFive()) { |
| 126 | 112 | 1, 2, 3 => 1, |
| 127 | 113 | 4, 5, 6 => 2, |
| ... | ... | @@ -149,8 +135,6 @@ fn returnsFalse() -> bool { |
| 149 | 135 | Number.Three => |x| return x > 12.34, |
| 150 | 136 | } |
| 151 | 137 | } |
| 152 | fn switchOnConstEnumWithVar() { | |
| 153 | @setFnTest(this); | |
| 154 | ||
| 138 | test "switchOnConstEnumWithVar" { | |
| 155 | 139 | assert(!returnsFalse()); |
| 156 | 140 | } |
test/cases/switch_prong_err_enum.zig+1-3| ... | ... | @@ -21,9 +21,7 @@ fn doThing(form_id: u64) -> %FormValue { |
| 21 | 21 | } |
| 22 | 22 | } |
| 23 | 23 | |
| 24 | fn switchProngReturnsErrorEnum() { | |
| 25 | @setFnTest(this); | |
| 26 | ||
| 24 | test "switchProngReturnsErrorEnum" { | |
| 27 | 25 | %%doThing(17); |
| 28 | 26 | assert(read_count == 1); |
| 29 | 27 | } |
test/cases/switch_prong_implicit_cast.zig+1-3| ... | ... | @@ -15,9 +15,7 @@ fn foo(id: u64) -> %FormValue { |
| 15 | 15 | } |
| 16 | 16 | } |
| 17 | 17 | |
| 18 | fn switchProngImplicitCast() { | |
| 19 | @setFnTest(this); | |
| 20 | ||
| 18 | test "switchProngImplicitCast" { | |
| 21 | 19 | const result = switch (%%foo(2)) { |
| 22 | 20 | FormValue.One => false, |
| 23 | 21 | FormValue.Two => |x| x, |
test/cases/this.zig+3-9| ... | ... | @@ -28,15 +28,11 @@ fn factorial(x: i32) -> i32 { |
| 28 | 28 | } |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | fn thisReferToModuleCallPrivateFn() { | |
| 32 | @setFnTest(this); | |
| 33 | ||
| 31 | test "thisReferToModuleCallPrivateFn" { | |
| 34 | 32 | assert(module.add(1, 2) == 3); |
| 35 | 33 | } |
| 36 | 34 | |
| 37 | fn thisReferToContainer() { | |
| 38 | @setFnTest(this); | |
| 39 | ||
| 35 | test "thisReferToContainer" { | |
| 40 | 36 | var pt = Point(i32) { |
| 41 | 37 | .x = 12, |
| 42 | 38 | .y = 34, |
| ... | ... | @@ -46,8 +42,6 @@ fn thisReferToContainer() { |
| 46 | 42 | assert(pt.y == 35); |
| 47 | 43 | } |
| 48 | 44 | |
| 49 | fn thisReferToFn() { | |
| 50 | @setFnTest(this); | |
| 51 | ||
| 45 | test "thisReferToFn" { | |
| 52 | 46 | assert(factorial(5) == 120); |
| 53 | 47 | } |
test/cases/try.zig+2-6| ... | ... | @@ -1,8 +1,6 @@ |
| 1 | 1 | const assert = @import("std").debug.assert; |
| 2 | 2 | |
| 3 | fn tryOnErrorUnion() { | |
| 4 | @setFnTest(this); | |
| 5 | ||
| 3 | test "tryOnErrorUnion" { | |
| 6 | 4 | tryOnErrorUnionImpl(); |
| 7 | 5 | comptime tryOnErrorUnionImpl(); |
| 8 | 6 | |
| ... | ... | @@ -25,9 +23,7 @@ fn returnsTen() -> %i32 { |
| 25 | 23 | 10 |
| 26 | 24 | } |
| 27 | 25 | |
| 28 | fn tryWithoutVars() { | |
| 29 | @setFnTest(this); | |
| 30 | ||
| 26 | test "tryWithoutVars" { | |
| 31 | 27 | const result1 = try (failIfTrue(true)) { |
| 32 | 28 | 1 |
| 33 | 29 | } else { |
test/cases/typedef.zig+1-3| ... | ... | @@ -5,8 +5,6 @@ type int = u8; |
| 5 | 5 | fn add(a: int, b: int) -> int { |
| 6 | 6 | a + b |
| 7 | 7 | } |
| 8 | fn typedef() { | |
| 9 | @setFnTest(this); | |
| 10 | ||
| 8 | test "typedef" { | |
| 11 | 9 | assert(add(12, 34) == 46); |
| 12 | 10 | } |
test/cases/undefined.zig+3-9| ... | ... | @@ -9,9 +9,7 @@ fn initStaticArray() -> [10]i32 { |
| 9 | 9 | return array; |
| 10 | 10 | } |
| 11 | 11 | const static_array = initStaticArray(); |
| 12 | fn initStaticArrayToUndefined() { | |
| 13 | @setFnTest(this); | |
| 14 | ||
| 12 | test "initStaticArrayToUndefined" { | |
| 15 | 13 | assert(static_array[0] == 1); |
| 16 | 14 | assert(static_array[4] == 2); |
| 17 | 15 | assert(static_array[7] == 3); |
| ... | ... | @@ -37,9 +35,7 @@ fn setFooX(foo: &Foo) { |
| 37 | 35 | foo.x = 2; |
| 38 | 36 | } |
| 39 | 37 | |
| 40 | fn assignUndefinedToStruct() { | |
| 41 | @setFnTest(this); | |
| 42 | ||
| 38 | test "assignUndefinedToStruct" { | |
| 43 | 39 | comptime { |
| 44 | 40 | var foo: Foo = undefined; |
| 45 | 41 | setFooX(&foo); |
| ... | ... | @@ -52,9 +48,7 @@ fn assignUndefinedToStruct() { |
| 52 | 48 | } |
| 53 | 49 | } |
| 54 | 50 | |
| 55 | fn assignUndefinedToStructWithMethod() { | |
| 56 | @setFnTest(this); | |
| 57 | ||
| 51 | test "assignUndefinedToStructWithMethod" { | |
| 58 | 52 | comptime { |
| 59 | 53 | var foo: Foo = undefined; |
| 60 | 54 | foo.setFooXMethod(); |
test/cases/var_args.zig+3-9| ... | ... | @@ -8,9 +8,7 @@ fn add(args: ...) -> i32 { |
| 8 | 8 | return sum; |
| 9 | 9 | } |
| 10 | 10 | |
| 11 | fn testAddArbitraryArgs() { | |
| 12 | @setFnTest(this); | |
| 13 | ||
| 11 | test "testAddArbitraryArgs" { | |
| 14 | 12 | assert(add(i32(1), i32(2), i32(3), i32(4)) == 10); |
| 15 | 13 | assert(add(i32(1234)) == 1234); |
| 16 | 14 | assert(add() == 0); |
| ... | ... | @@ -20,15 +18,11 @@ fn readFirstVarArg(args: ...) { |
| 20 | 18 | const value = args[0]; |
| 21 | 19 | } |
| 22 | 20 | |
| 23 | fn sendVoidArgToVarArgs() { | |
| 24 | @setFnTest(this); | |
| 25 | ||
| 21 | test "sendVoidArgToVarArgs" { | |
| 26 | 22 | readFirstVarArg({}); |
| 27 | 23 | } |
| 28 | 24 | |
| 29 | fn testPassArgsDirectly() { | |
| 30 | @setFnTest(this); | |
| 31 | ||
| 25 | test "testPassArgsDirectly" { | |
| 32 | 26 | assert(addSomeStuff(i32(1), i32(2), i32(3), i32(4)) == 10); |
| 33 | 27 | assert(addSomeStuff(i32(1234)) == 1234); |
| 34 | 28 | assert(addSomeStuff() == 0); |
test/cases/void.zig+1-3| ... | ... | @@ -6,9 +6,7 @@ const Foo = struct { |
| 6 | 6 | c: void, |
| 7 | 7 | }; |
| 8 | 8 | |
| 9 | fn compareVoidWithVoidCompileTimeKnown() { | |
| 10 | @setFnTest(this); | |
| 11 | ||
| 9 | test "compareVoidWithVoidCompileTimeKnown" { | |
| 12 | 10 | comptime { |
| 13 | 11 | const foo = Foo { |
| 14 | 12 | .a = {}, |
test/cases/while.zig+5-15| ... | ... | @@ -1,8 +1,6 @@ |
| 1 | 1 | const assert = @import("std").debug.assert; |
| 2 | 2 | |
| 3 | fn whileLoop() { | |
| 4 | @setFnTest(this); | |
| 5 | ||
| 3 | test "whileLoop" { | |
| 6 | 4 | var i : i32 = 0; |
| 7 | 5 | while (i < 4) { |
| 8 | 6 | i += 1; |
| ... | ... | @@ -18,9 +16,7 @@ fn whileLoop2() -> i32 { |
| 18 | 16 | return 1; |
| 19 | 17 | } |
| 20 | 18 | } |
| 21 | fn staticEvalWhile() { | |
| 22 | @setFnTest(this); | |
| 23 | ||
| 19 | test "staticEvalWhile" { | |
| 24 | 20 | assert(static_eval_while_number == 1); |
| 25 | 21 | } |
| 26 | 22 | const static_eval_while_number = staticWhileLoop1(); |
| ... | ... | @@ -33,9 +29,7 @@ fn staticWhileLoop2() -> i32 { |
| 33 | 29 | } |
| 34 | 30 | } |
| 35 | 31 | |
| 36 | fn continueAndBreak() { | |
| 37 | @setFnTest(this); | |
| 38 | ||
| 32 | test "continueAndBreak" { | |
| 39 | 33 | runContinueAndBreakTest(); |
| 40 | 34 | assert(continue_and_break_counter == 8); |
| 41 | 35 | } |
| ... | ... | @@ -53,9 +47,7 @@ fn runContinueAndBreakTest() { |
| 53 | 47 | assert(i == 4); |
| 54 | 48 | } |
| 55 | 49 | |
| 56 | fn returnWithImplicitCastFromWhileLoop() { | |
| 57 | @setFnTest(this); | |
| 58 | ||
| 50 | test "returnWithImplicitCastFromWhileLoop" { | |
| 59 | 51 | %%returnWithImplicitCastFromWhileLoopTest(); |
| 60 | 52 | } |
| 61 | 53 | fn returnWithImplicitCastFromWhileLoopTest() -> %void { |
| ... | ... | @@ -64,9 +56,7 @@ fn returnWithImplicitCastFromWhileLoopTest() -> %void { |
| 64 | 56 | } |
| 65 | 57 | } |
| 66 | 58 | |
| 67 | fn whileWithContinueExpr() { | |
| 68 | @setFnTest(this); | |
| 69 | ||
| 59 | test "whileWithContinueExpr" { | |
| 70 | 60 | var sum: i32 = 0; |
| 71 | 61 | {var i: i32 = 0; while (i < 10; i += 1) { |
| 72 | 62 | if (i == 5) continue; |
test/run_tests.cpp+223-88| ... | ... | @@ -14,6 +14,12 @@ |
| 14 | 14 | #include <stdio.h> |
| 15 | 15 | #include <stdarg.h> |
| 16 | 16 | |
| 17 | enum TestSpecial { | |
| 18 | TestSpecialNone, | |
| 19 | TestSpecialSelfHosted, | |
| 20 | TestSpecialStd, | |
| 21 | }; | |
| 22 | ||
| 17 | 23 | struct TestSourceFile { |
| 18 | 24 | const char *relative_path; |
| 19 | 25 | const char *source_code; |
| ... | ... | @@ -32,7 +38,7 @@ struct TestCase { |
| 32 | 38 | ZigList<const char *> compiler_args; |
| 33 | 39 | ZigList<const char *> program_args; |
| 34 | 40 | bool is_parseh; |
| 35 | bool is_self_hosted; | |
| 41 | TestSpecial special; | |
| 36 | 42 | bool is_release_mode; |
| 37 | 43 | bool is_debug_safety; |
| 38 | 44 | AllowWarnings allow_warnings; |
| ... | ... | @@ -79,7 +85,6 @@ static TestCase *add_simple_case(const char *case_name, const char *source, cons |
| 79 | 85 | test_case->compiler_args.append("--strip"); |
| 80 | 86 | test_case->compiler_args.append("--color"); |
| 81 | 87 | test_case->compiler_args.append("on"); |
| 82 | test_case->compiler_args.append("--check-unused"); | |
| 83 | 88 | |
| 84 | 89 | test_cases.append(test_case); |
| 85 | 90 | |
| ... | ... | @@ -93,9 +98,10 @@ static TestCase *add_simple_case_libc(const char *case_name, const char *source, |
| 93 | 98 | return tc; |
| 94 | 99 | } |
| 95 | 100 | |
| 96 | static TestCase *add_compile_fail_case_extra(const char *case_name, const char *source, bool check_unused, | |
| 97 | size_t count, va_list ap) | |
| 98 | { | |
| 101 | static TestCase *add_compile_fail_case(const char *case_name, const char *source, size_t count, ...) { | |
| 102 | va_list ap; | |
| 103 | va_start(ap, count); | |
| 104 | ||
| 99 | 105 | TestCase *test_case = allocate<TestCase>(1); |
| 100 | 106 | test_case->case_name = case_name; |
| 101 | 107 | test_case->source_files.resize(1); |
| ... | ... | @@ -122,31 +128,11 @@ static TestCase *add_compile_fail_case_extra(const char *case_name, const char * |
| 122 | 128 | test_case->compiler_args.append("--release"); |
| 123 | 129 | test_case->compiler_args.append("--strip"); |
| 124 | 130 | |
| 125 | if (check_unused) { | |
| 126 | test_case->compiler_args.append("--check-unused"); | |
| 127 | } | |
| 128 | ||
| 129 | 131 | test_cases.append(test_case); |
| 130 | 132 | |
| 131 | 133 | return test_case; |
| 132 | 134 | } |
| 133 | 135 | |
| 134 | static TestCase *add_compile_fail_case_no_check_unused(const char *case_name, const char *source, size_t count, ...) { | |
| 135 | va_list ap; | |
| 136 | va_start(ap, count); | |
| 137 | TestCase *result = add_compile_fail_case_extra(case_name, source, false, count, ap); | |
| 138 | va_end(ap); | |
| 139 | return result; | |
| 140 | } | |
| 141 | ||
| 142 | static TestCase *add_compile_fail_case(const char *case_name, const char *source, size_t count, ...) { | |
| 143 | va_list ap; | |
| 144 | va_start(ap, count); | |
| 145 | TestCase *result = add_compile_fail_case_extra(case_name, source, true, count, ap); | |
| 146 | va_end(ap); | |
| 147 | return result; | |
| 148 | } | |
| 149 | ||
| 150 | 136 | static void add_debug_safety_case(const char *case_name, const char *source) { |
| 151 | 137 | { |
| 152 | 138 | TestCase *test_case = allocate<TestCase>(1); |
| ... | ... | @@ -674,24 +660,27 @@ static void add_compile_failure_test_cases(void) { |
| 674 | 660 | add_compile_fail_case("multiple function definitions", R"SOURCE( |
| 675 | 661 | fn a() {} |
| 676 | 662 | fn a() {} |
| 663 | export fn entry() { a(); } | |
| 677 | 664 | )SOURCE", 1, ".tmp_source.zig:3:1: error: redefinition of 'a'"); |
| 678 | 665 | |
| 679 | 666 | add_compile_fail_case("unreachable with return", R"SOURCE( |
| 680 | 667 | fn a() -> unreachable {return;} |
| 668 | export fn entry() { a(); } | |
| 681 | 669 | )SOURCE", 1, ".tmp_source.zig:2:24: error: expected type 'unreachable', found 'void'"); |
| 682 | 670 | |
| 683 | 671 | add_compile_fail_case("control reaches end of non-void function", R"SOURCE( |
| 684 | 672 | fn a() -> i32 {} |
| 673 | export fn entry() { _ = a(); } | |
| 685 | 674 | )SOURCE", 1, ".tmp_source.zig:2:15: error: expected type 'i32', found 'void'"); |
| 686 | 675 | |
| 687 | 676 | add_compile_fail_case("undefined function call", R"SOURCE( |
| 688 | fn a() { | |
| 677 | export fn a() { | |
| 689 | 678 | b(); |
| 690 | 679 | } |
| 691 | 680 | )SOURCE", 1, ".tmp_source.zig:3:5: error: use of undeclared identifier 'b'"); |
| 692 | 681 | |
| 693 | 682 | add_compile_fail_case("wrong number of arguments", R"SOURCE( |
| 694 | fn a() { | |
| 683 | export fn a() { | |
| 695 | 684 | b(1); |
| 696 | 685 | } |
| 697 | 686 | fn b(a: i32, b: i32, c: i32) { } |
| ... | ... | @@ -699,14 +688,16 @@ fn b(a: i32, b: i32, c: i32) { } |
| 699 | 688 | |
| 700 | 689 | add_compile_fail_case("invalid type", R"SOURCE( |
| 701 | 690 | fn a() -> bogus {} |
| 691 | export fn entry() { _ = a(); } | |
| 702 | 692 | )SOURCE", 1, ".tmp_source.zig:2:11: error: use of undeclared identifier 'bogus'"); |
| 703 | 693 | |
| 704 | 694 | add_compile_fail_case("pointer to unreachable", R"SOURCE( |
| 705 | 695 | fn a() -> &unreachable {} |
| 696 | export fn entry() { _ = a(); } | |
| 706 | 697 | )SOURCE", 1, ".tmp_source.zig:2:12: error: pointer to unreachable not allowed"); |
| 707 | 698 | |
| 708 | 699 | add_compile_fail_case("unreachable code", R"SOURCE( |
| 709 | fn a() { | |
| 700 | export fn a() { | |
| 710 | 701 | return; |
| 711 | 702 | b(); |
| 712 | 703 | } |
| ... | ... | @@ -716,10 +707,11 @@ fn b() {} |
| 716 | 707 | |
| 717 | 708 | add_compile_fail_case("bad import", R"SOURCE( |
| 718 | 709 | const bogus = @import("bogus-does-not-exist.zig"); |
| 710 | export fn entry() { bogus.bogo(); } | |
| 719 | 711 | )SOURCE", 1, ".tmp_source.zig:2:15: error: unable to find 'bogus-does-not-exist.zig'"); |
| 720 | 712 | |
| 721 | 713 | add_compile_fail_case("undeclared identifier", R"SOURCE( |
| 722 | fn a() { | |
| 714 | export fn a() { | |
| 723 | 715 | b + |
| 724 | 716 | c |
| 725 | 717 | } |
| ... | ... | @@ -730,10 +722,11 @@ fn a() { |
| 730 | 722 | add_compile_fail_case("parameter redeclaration", R"SOURCE( |
| 731 | 723 | fn f(a : i32, a : i32) { |
| 732 | 724 | } |
| 725 | export fn entry() { f(1, 2); } | |
| 733 | 726 | )SOURCE", 1, ".tmp_source.zig:2:15: error: redeclaration of variable 'a'"); |
| 734 | 727 | |
| 735 | 728 | add_compile_fail_case("local variable redeclaration", R"SOURCE( |
| 736 | fn f() { | |
| 729 | export fn f() { | |
| 737 | 730 | const a : i32 = 0; |
| 738 | 731 | const a = 0; |
| 739 | 732 | } |
| ... | ... | @@ -743,71 +736,73 @@ fn f() { |
| 743 | 736 | fn f(a : i32) { |
| 744 | 737 | const a = 0; |
| 745 | 738 | } |
| 739 | export fn entry() { f(1); } | |
| 746 | 740 | )SOURCE", 1, ".tmp_source.zig:3:5: error: redeclaration of variable 'a'"); |
| 747 | 741 | |
| 748 | 742 | add_compile_fail_case("variable has wrong type", R"SOURCE( |
| 749 | fn f() -> i32 { | |
| 743 | export fn f() -> i32 { | |
| 750 | 744 | const a = c"a"; |
| 751 | 745 | a |
| 752 | 746 | } |
| 753 | 747 | )SOURCE", 1, ".tmp_source.zig:4:5: error: expected type 'i32', found '&const u8'"); |
| 754 | 748 | |
| 755 | 749 | add_compile_fail_case("if condition is bool, not int", R"SOURCE( |
| 756 | fn f() { | |
| 750 | export fn f() { | |
| 757 | 751 | if (0) {} |
| 758 | 752 | } |
| 759 | 753 | )SOURCE", 1, ".tmp_source.zig:3:9: error: integer value 0 cannot be implicitly casted to type 'bool'"); |
| 760 | 754 | |
| 761 | 755 | add_compile_fail_case("assign unreachable", R"SOURCE( |
| 762 | fn f() { | |
| 756 | export fn f() { | |
| 763 | 757 | const a = return; |
| 764 | 758 | } |
| 765 | 759 | )SOURCE", 1, ".tmp_source.zig:3:5: error: unreachable code"); |
| 766 | 760 | |
| 767 | 761 | add_compile_fail_case("unreachable variable", R"SOURCE( |
| 768 | fn f() { | |
| 762 | export fn f() { | |
| 769 | 763 | const a : unreachable = {}; |
| 770 | 764 | } |
| 771 | 765 | )SOURCE", 1, ".tmp_source.zig:3:15: error: variable of type 'unreachable' not allowed"); |
| 772 | 766 | |
| 773 | 767 | add_compile_fail_case("unreachable parameter", R"SOURCE( |
| 774 | 768 | fn f(a : unreachable) {} |
| 769 | export fn entry() { f(); } | |
| 775 | 770 | )SOURCE", 1, ".tmp_source.zig:2:10: error: parameter of type 'unreachable' not allowed"); |
| 776 | 771 | |
| 777 | 772 | add_compile_fail_case("bad assignment target", R"SOURCE( |
| 778 | fn f() { | |
| 773 | export fn f() { | |
| 779 | 774 | 3 = 3; |
| 780 | 775 | } |
| 781 | 776 | )SOURCE", 1, ".tmp_source.zig:3:7: error: cannot assign to constant"); |
| 782 | 777 | |
| 783 | 778 | add_compile_fail_case("assign to constant variable", R"SOURCE( |
| 784 | fn f() { | |
| 779 | export fn f() { | |
| 785 | 780 | const a = 3; |
| 786 | 781 | a = 4; |
| 787 | 782 | } |
| 788 | 783 | )SOURCE", 1, ".tmp_source.zig:4:7: error: cannot assign to constant"); |
| 789 | 784 | |
| 790 | 785 | add_compile_fail_case("use of undeclared identifier", R"SOURCE( |
| 791 | fn f() { | |
| 786 | export fn f() { | |
| 792 | 787 | b = 3; |
| 793 | 788 | } |
| 794 | 789 | )SOURCE", 1, ".tmp_source.zig:3:5: error: use of undeclared identifier 'b'"); |
| 795 | 790 | |
| 796 | 791 | add_compile_fail_case("const is a statement, not an expression", R"SOURCE( |
| 797 | fn f() { | |
| 792 | export fn f() { | |
| 798 | 793 | (const a = 0); |
| 799 | 794 | } |
| 800 | 795 | )SOURCE", 1, ".tmp_source.zig:3:6: error: invalid token: 'const'"); |
| 801 | 796 | |
| 802 | 797 | add_compile_fail_case("array access of undeclared identifier", R"SOURCE( |
| 803 | fn f() { | |
| 798 | export fn f() { | |
| 804 | 799 | i[i] = i[i]; |
| 805 | 800 | } |
| 806 | 801 | )SOURCE", 2, ".tmp_source.zig:3:5: error: use of undeclared identifier 'i'", |
| 807 | 802 | ".tmp_source.zig:3:12: error: use of undeclared identifier 'i'"); |
| 808 | 803 | |
| 809 | 804 | add_compile_fail_case("array access of non array", R"SOURCE( |
| 810 | fn f() { | |
| 805 | export fn f() { | |
| 811 | 806 | var bad : bool = undefined; |
| 812 | 807 | bad[bad] = bad[bad]; |
| 813 | 808 | } |
| ... | ... | @@ -815,7 +810,7 @@ fn f() { |
| 815 | 810 | ".tmp_source.zig:4:19: error: array access of non-array type 'bool'"); |
| 816 | 811 | |
| 817 | 812 | add_compile_fail_case("array access with non integer index", R"SOURCE( |
| 818 | fn f() { | |
| 813 | export fn f() { | |
| 819 | 814 | var array = "aoeu"; |
| 820 | 815 | var bad = false; |
| 821 | 816 | array[bad] = array[bad]; |
| ... | ... | @@ -828,6 +823,7 @@ const x : i32 = 99; |
| 828 | 823 | fn f() { |
| 829 | 824 | x = 1; |
| 830 | 825 | } |
| 826 | export fn entry() { f(); } | |
| 831 | 827 | )SOURCE", 1, ".tmp_source.zig:4:7: error: cannot assign to constant"); |
| 832 | 828 | |
| 833 | 829 | |
| ... | ... | @@ -836,22 +832,25 @@ fn f(b: bool) { |
| 836 | 832 | const x : i32 = if (b) { 1 }; |
| 837 | 833 | const y = if (b) { i32(1) }; |
| 838 | 834 | } |
| 835 | export fn entry() { f(true); } | |
| 839 | 836 | )SOURCE", 2, ".tmp_source.zig:3:30: error: integer value 1 cannot be implicitly casted to type 'void'", |
| 840 | 837 | ".tmp_source.zig:4:15: error: incompatible types: 'i32' and 'void'"); |
| 841 | 838 | |
| 842 | 839 | add_compile_fail_case("direct struct loop", R"SOURCE( |
| 843 | 840 | const A = struct { a : A, }; |
| 841 | export fn entry() -> usize { @sizeOf(A) } | |
| 844 | 842 | )SOURCE", 1, ".tmp_source.zig:2:11: error: struct 'A' contains itself"); |
| 845 | 843 | |
| 846 | 844 | add_compile_fail_case("indirect struct loop", R"SOURCE( |
| 847 | 845 | const A = struct { b : B, }; |
| 848 | 846 | const B = struct { c : C, }; |
| 849 | 847 | const C = struct { a : A, }; |
| 848 | export fn entry() -> usize { @sizeOf(A) } | |
| 850 | 849 | )SOURCE", 1, ".tmp_source.zig:2:11: error: struct 'A' contains itself"); |
| 851 | 850 | |
| 852 | 851 | add_compile_fail_case("invalid struct field", R"SOURCE( |
| 853 | 852 | const A = struct { x : i32, }; |
| 854 | fn f() { | |
| 853 | export fn f() { | |
| 855 | 854 | var a : A = undefined; |
| 856 | 855 | a.foo = 1; |
| 857 | 856 | const y = a.bar; |
| ... | ... | @@ -873,7 +872,9 @@ const A = enum {}; |
| 873 | 872 | add_compile_fail_case("redefinition of global variables", R"SOURCE( |
| 874 | 873 | var a : i32 = 1; |
| 875 | 874 | var a : i32 = 2; |
| 876 | )SOURCE", 1, ".tmp_source.zig:3:1: error: redeclaration of variable 'a'"); | |
| 875 | )SOURCE", 2, | |
| 876 | ".tmp_source.zig:3:1: error: redefinition of 'a'", | |
| 877 | ".tmp_source.zig:2:1: note: previous definition is here"); | |
| 877 | 878 | |
| 878 | 879 | add_compile_fail_case("byvalue struct parameter in exported function", R"SOURCE( |
| 879 | 880 | const A = struct { x : i32, }; |
| ... | ... | @@ -893,7 +894,7 @@ const A = struct { |
| 893 | 894 | y : i32, |
| 894 | 895 | z : i32, |
| 895 | 896 | }; |
| 896 | fn f() { | |
| 897 | export fn f() { | |
| 897 | 898 | const a = A { |
| 898 | 899 | .z = 1, |
| 899 | 900 | .y = 2, |
| ... | ... | @@ -909,7 +910,7 @@ const A = struct { |
| 909 | 910 | y : i32, |
| 910 | 911 | z : i32, |
| 911 | 912 | }; |
| 912 | fn f() { | |
| 913 | export fn f() { | |
| 913 | 914 | // we want the error on the '{' not the 'A' because |
| 914 | 915 | // the A could be a complicated expression |
| 915 | 916 | const a = A { |
| ... | ... | @@ -925,7 +926,7 @@ const A = struct { |
| 925 | 926 | y : i32, |
| 926 | 927 | z : i32, |
| 927 | 928 | }; |
| 928 | fn f() { | |
| 929 | export fn f() { | |
| 929 | 930 | const a = A { |
| 930 | 931 | .z = 4, |
| 931 | 932 | .y = 2, |
| ... | ... | @@ -935,19 +936,19 @@ fn f() { |
| 935 | 936 | )SOURCE", 1, ".tmp_source.zig:11:9: error: no member named 'foo' in 'A'"); |
| 936 | 937 | |
| 937 | 938 | add_compile_fail_case("invalid break expression", R"SOURCE( |
| 938 | fn f() { | |
| 939 | export fn f() { | |
| 939 | 940 | break; |
| 940 | 941 | } |
| 941 | 942 | )SOURCE", 1, ".tmp_source.zig:3:5: error: 'break' expression outside loop"); |
| 942 | 943 | |
| 943 | 944 | add_compile_fail_case("invalid continue expression", R"SOURCE( |
| 944 | fn f() { | |
| 945 | export fn f() { | |
| 945 | 946 | continue; |
| 946 | 947 | } |
| 947 | 948 | )SOURCE", 1, ".tmp_source.zig:3:5: error: 'continue' expression outside loop"); |
| 948 | 949 | |
| 949 | 950 | add_compile_fail_case("invalid maybe type", R"SOURCE( |
| 950 | fn f() { | |
| 951 | export fn f() { | |
| 951 | 952 | if (const x ?= true) { } |
| 952 | 953 | } |
| 953 | 954 | )SOURCE", 1, ".tmp_source.zig:3:20: error: expected nullable type, found 'bool'"); |
| ... | ... | @@ -956,42 +957,39 @@ fn f() { |
| 956 | 957 | fn f() -> i32 { |
| 957 | 958 | i32(return 1) |
| 958 | 959 | } |
| 960 | export fn entry() { _ = f(); } | |
| 959 | 961 | )SOURCE", 1, ".tmp_source.zig:3:8: error: unreachable code"); |
| 960 | 962 | |
| 961 | 963 | add_compile_fail_case("invalid builtin fn", R"SOURCE( |
| 962 | 964 | fn f() -> @bogus(foo) { |
| 963 | 965 | } |
| 966 | export fn entry() { _ = f(); } | |
| 964 | 967 | )SOURCE", 1, ".tmp_source.zig:2:11: error: invalid builtin function: 'bogus'"); |
| 965 | 968 | |
| 966 | 969 | add_compile_fail_case("top level decl dependency loop", R"SOURCE( |
| 967 | 970 | const a : @typeOf(b) = 0; |
| 968 | 971 | const b : @typeOf(a) = 0; |
| 972 | export fn entry() { | |
| 973 | const c = a + b; | |
| 974 | } | |
| 969 | 975 | )SOURCE", 1, ".tmp_source.zig:2:1: error: 'a' depends on itself"); |
| 970 | 976 | |
| 971 | 977 | add_compile_fail_case("noalias on non pointer param", R"SOURCE( |
| 972 | 978 | fn f(noalias x: i32) {} |
| 979 | export fn entry() { f(1234); } | |
| 973 | 980 | )SOURCE", 1, ".tmp_source.zig:2:6: error: noalias on non-pointer parameter"); |
| 974 | 981 | |
| 975 | 982 | add_compile_fail_case("struct init syntax for array", R"SOURCE( |
| 976 | 983 | const foo = []u16{.x = 1024,}; |
| 984 | export fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 977 | 985 | )SOURCE", 1, ".tmp_source.zig:2:18: error: type '[]u16' does not support struct initialization syntax"); |
| 978 | 986 | |
| 979 | 987 | add_compile_fail_case("type variables must be constant", R"SOURCE( |
| 980 | 988 | var foo = u8; |
| 981 | )SOURCE", 1, ".tmp_source.zig:2:1: error: variable of type 'type' must be constant"); | |
| 982 | ||
| 983 | add_compile_fail_case("variables shadowing types", R"SOURCE( | |
| 984 | const Foo = struct {}; | |
| 985 | const Bar = struct {}; | |
| 986 | ||
| 987 | fn f(Foo: i32) { | |
| 988 | var Bar : i32 = undefined; | |
| 989 | export fn entry() -> foo { | |
| 990 | return 1; | |
| 989 | 991 | } |
| 990 | )SOURCE", 4, | |
| 991 | ".tmp_source.zig:5:6: error: redeclaration of variable 'Foo'", | |
| 992 | ".tmp_source.zig:2:1: note: previous declaration is here", | |
| 993 | ".tmp_source.zig:6:5: error: redeclaration of variable 'Bar'", | |
| 994 | ".tmp_source.zig:3:1: note: previous declaration is here"); | |
| 992 | )SOURCE", 1, ".tmp_source.zig:2:1: error: variable of type 'type' must be constant"); | |
| 995 | 993 | |
| 996 | 994 | add_compile_fail_case("multiple else prongs in a switch", R"SOURCE( |
| 997 | 995 | fn f(x: u32) { |
| ... | ... | @@ -1000,28 +998,36 @@ fn f(x: u32) { |
| 1000 | 998 | else => true, |
| 1001 | 999 | else => true, |
| 1002 | 1000 | }; |
| 1001 | } | |
| 1002 | export fn entry() { | |
| 1003 | f(1234); | |
| 1003 | 1004 | } |
| 1004 | 1005 | )SOURCE", 1, ".tmp_source.zig:6:9: error: multiple else prongs in switch expression"); |
| 1005 | 1006 | |
| 1006 | 1007 | add_compile_fail_case("global variable initializer must be constant expression", R"SOURCE( |
| 1007 | 1008 | extern fn foo() -> i32; |
| 1008 | 1009 | const x = foo(); |
| 1010 | export fn entry() -> i32 { x } | |
| 1009 | 1011 | )SOURCE", 1, ".tmp_source.zig:3:11: error: unable to evaluate constant expression"); |
| 1010 | 1012 | |
| 1011 | 1013 | add_compile_fail_case("array concatenation with wrong type", R"SOURCE( |
| 1012 | 1014 | const src = "aoeu"; |
| 1013 | 1015 | const derp = usize(1234); |
| 1014 | 1016 | const a = derp ++ "foo"; |
| 1017 | ||
| 1018 | export fn entry() -> usize { @sizeOf(@typeOf(a)) } | |
| 1015 | 1019 | )SOURCE", 1, ".tmp_source.zig:4:11: error: expected array or C string literal, found 'usize'"); |
| 1016 | 1020 | |
| 1017 | 1021 | add_compile_fail_case("non compile time array concatenation", R"SOURCE( |
| 1018 | 1022 | fn f(s: [10]u8) -> []u8 { |
| 1019 | 1023 | s ++ "foo" |
| 1020 | 1024 | } |
| 1025 | export fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 1021 | 1026 | )SOURCE", 1, ".tmp_source.zig:3:5: error: unable to evaluate constant expression"); |
| 1022 | 1027 | |
| 1023 | 1028 | add_compile_fail_case("@cImport with bogus include", R"SOURCE( |
| 1024 | 1029 | const c = @cImport(@cInclude("bogus.h")); |
| 1030 | export fn entry() -> usize { @sizeOf(@typeOf(c.bogo)) } | |
| 1025 | 1031 | )SOURCE", 2, ".tmp_source.zig:2:11: error: C import failed", |
| 1026 | 1032 | ".h:1:10: note: 'bogus.h' file not found"); |
| 1027 | 1033 | |
| ... | ... | @@ -1029,14 +1035,17 @@ const c = @cImport(@cInclude("bogus.h")); |
| 1029 | 1035 | const x = 3; |
| 1030 | 1036 | const y = &x; |
| 1031 | 1037 | fn foo() -> &const i32 { y } |
| 1038 | export fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 1032 | 1039 | )SOURCE", 1, ".tmp_source.zig:4:26: error: expected type '&const i32', found '&const (integer literal)'"); |
| 1033 | 1040 | |
| 1034 | 1041 | add_compile_fail_case("integer overflow error", R"SOURCE( |
| 1035 | 1042 | const x : u8 = 300; |
| 1043 | export fn entry() -> usize { @sizeOf(@typeOf(x)) } | |
| 1036 | 1044 | )SOURCE", 1, ".tmp_source.zig:2:16: error: integer value 300 cannot be implicitly casted to type 'u8'"); |
| 1037 | 1045 | |
| 1038 | 1046 | add_compile_fail_case("incompatible number literals", R"SOURCE( |
| 1039 | 1047 | const x = 2 == 2.0; |
| 1048 | export fn entry() -> usize { @sizeOf(@typeOf(x)) } | |
| 1040 | 1049 | )SOURCE", 1, ".tmp_source.zig:2:11: error: integer value 2 cannot be implicitly casted to type '(float literal)'"); |
| 1041 | 1050 | |
| 1042 | 1051 | add_compile_fail_case("missing function call param", R"SOURCE( |
| ... | ... | @@ -1061,11 +1070,14 @@ const members = []member_fn_type { |
| 1061 | 1070 | fn f(foo: Foo, index: usize) { |
| 1062 | 1071 | const result = members[index](); |
| 1063 | 1072 | } |
| 1073 | ||
| 1074 | export fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 1064 | 1075 | )SOURCE", 1, ".tmp_source.zig:21:34: error: expected 1 arguments, found 0"); |
| 1065 | 1076 | |
| 1066 | 1077 | add_compile_fail_case("missing function name and param name", R"SOURCE( |
| 1067 | 1078 | fn () {} |
| 1068 | 1079 | fn f(i32) {} |
| 1080 | export fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 1069 | 1081 | )SOURCE", 2, |
| 1070 | 1082 | ".tmp_source.zig:2:1: error: missing function name", |
| 1071 | 1083 | ".tmp_source.zig:3:6: error: missing parameter name"); |
| ... | ... | @@ -1075,6 +1087,7 @@ const fns = []fn(){ a, b, c }; |
| 1075 | 1087 | fn a() -> i32 {0} |
| 1076 | 1088 | fn b() -> i32 {1} |
| 1077 | 1089 | fn c() -> i32 {2} |
| 1090 | export fn entry() -> usize { @sizeOf(@typeOf(fns)) } | |
| 1078 | 1091 | )SOURCE", 1, ".tmp_source.zig:2:21: error: expected type 'fn()', found 'fn() -> i32'"); |
| 1079 | 1092 | |
| 1080 | 1093 | add_compile_fail_case("extern function pointer mismatch", R"SOURCE( |
| ... | ... | @@ -1082,18 +1095,23 @@ const fns = [](fn(i32)->i32){ a, b, c }; |
| 1082 | 1095 | pub fn a(x: i32) -> i32 {x + 0} |
| 1083 | 1096 | pub fn b(x: i32) -> i32 {x + 1} |
| 1084 | 1097 | export fn c(x: i32) -> i32 {x + 2} |
| 1098 | ||
| 1099 | export fn entry() -> usize { @sizeOf(@typeOf(fns)) } | |
| 1085 | 1100 | )SOURCE", 1, ".tmp_source.zig:2:37: error: expected type 'fn(i32) -> i32', found 'extern fn(i32) -> i32'"); |
| 1086 | 1101 | |
| 1087 | 1102 | |
| 1088 | 1103 | add_compile_fail_case("implicit cast from f64 to f32", R"SOURCE( |
| 1089 | 1104 | const x : f64 = 1.0; |
| 1090 | 1105 | const y : f32 = x; |
| 1106 | ||
| 1107 | export fn entry() -> usize { @sizeOf(@typeOf(y)) } | |
| 1091 | 1108 | )SOURCE", 1, ".tmp_source.zig:3:17: error: expected type 'f32', found 'f64'"); |
| 1092 | 1109 | |
| 1093 | 1110 | |
| 1094 | 1111 | add_compile_fail_case("colliding invalid top level functions", R"SOURCE( |
| 1095 | 1112 | fn func() -> bogus {} |
| 1096 | 1113 | fn func() -> bogus {} |
| 1114 | export fn entry() -> usize { @sizeOf(@typeOf(func)) } | |
| 1097 | 1115 | )SOURCE", 2, |
| 1098 | 1116 | ".tmp_source.zig:3:1: error: redefinition of 'func'", |
| 1099 | 1117 | ".tmp_source.zig:2:14: error: use of undeclared identifier 'bogus'"); |
| ... | ... | @@ -1101,6 +1119,7 @@ fn func() -> bogus {} |
| 1101 | 1119 | |
| 1102 | 1120 | add_compile_fail_case("bogus compile var", R"SOURCE( |
| 1103 | 1121 | const x = @compileVar("bogus"); |
| 1122 | export fn entry() -> usize { @sizeOf(@typeOf(x)) } | |
| 1104 | 1123 | )SOURCE", 1, ".tmp_source.zig:2:23: error: unrecognized compile variable: 'bogus'"); |
| 1105 | 1124 | |
| 1106 | 1125 | |
| ... | ... | @@ -1110,6 +1129,8 @@ const Foo = struct { |
| 1110 | 1129 | }; |
| 1111 | 1130 | var global_var: usize = 1; |
| 1112 | 1131 | fn get() -> usize { global_var } |
| 1132 | ||
| 1133 | export fn entry() -> usize { @sizeOf(@typeOf(Foo)) } | |
| 1113 | 1134 | )SOURCE", 3, |
| 1114 | 1135 | ".tmp_source.zig:6:21: error: unable to evaluate constant expression", |
| 1115 | 1136 | ".tmp_source.zig:3:12: note: called from here", |
| ... | ... | @@ -1121,6 +1142,8 @@ const Foo = struct { |
| 1121 | 1142 | field: i32, |
| 1122 | 1143 | }; |
| 1123 | 1144 | const x = Foo {.field = 1} + Foo {.field = 2}; |
| 1145 | ||
| 1146 | export fn entry() -> usize { @sizeOf(@typeOf(x)) } | |
| 1124 | 1147 | )SOURCE", 1, ".tmp_source.zig:5:28: error: invalid operands to binary expression: 'Foo' and 'Foo'"); |
| 1125 | 1148 | |
| 1126 | 1149 | |
| ... | ... | @@ -1129,6 +1152,11 @@ const lit_int_x = 1 / 0; |
| 1129 | 1152 | const lit_float_x = 1.0 / 0.0; |
| 1130 | 1153 | const int_x = i32(1) / i32(0); |
| 1131 | 1154 | const float_x = f32(1.0) / f32(0.0); |
| 1155 | ||
| 1156 | export fn entry1() -> usize { @sizeOf(@typeOf(lit_int_x)) } | |
| 1157 | export fn entry2() -> usize { @sizeOf(@typeOf(lit_float_x)) } | |
| 1158 | export fn entry3() -> usize { @sizeOf(@typeOf(int_x)) } | |
| 1159 | export fn entry4() -> usize { @sizeOf(@typeOf(float_x)) } | |
| 1132 | 1160 | )SOURCE", 4, |
| 1133 | 1161 | ".tmp_source.zig:2:21: error: division by zero is undefined", |
| 1134 | 1162 | ".tmp_source.zig:3:25: error: division by zero is undefined", |
| ... | ... | @@ -1150,16 +1178,22 @@ fn f(n: Number) -> i32 { |
| 1150 | 1178 | Number.Three => i32(3), |
| 1151 | 1179 | } |
| 1152 | 1180 | } |
| 1181 | ||
| 1182 | export fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 1153 | 1183 | )SOURCE", 1, ".tmp_source.zig:9:5: error: enumeration value 'Number.Four' not handled in switch"); |
| 1154 | 1184 | |
| 1155 | 1185 | add_compile_fail_case("normal string with newline", R"SOURCE( |
| 1156 | 1186 | const foo = "a |
| 1157 | 1187 | b"; |
| 1188 | ||
| 1189 | export fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 1158 | 1190 | )SOURCE", 1, ".tmp_source.zig:2:13: error: newline not allowed in string literal"); |
| 1159 | 1191 | |
| 1160 | 1192 | add_compile_fail_case("invalid comparison for function pointers", R"SOURCE( |
| 1161 | 1193 | fn foo() {} |
| 1162 | 1194 | const invalid = foo > foo; |
| 1195 | ||
| 1196 | export fn entry() -> usize { @sizeOf(@typeOf(invalid)) } | |
| 1163 | 1197 | )SOURCE", 1, ".tmp_source.zig:3:21: error: operator not allowed for type 'fn()'"); |
| 1164 | 1198 | |
| 1165 | 1199 | add_compile_fail_case("generic function instance with non-constant expression", R"SOURCE( |
| ... | ... | @@ -1167,10 +1201,12 @@ fn foo(comptime x: i32, y: i32) -> i32 { return x + y; } |
| 1167 | 1201 | fn test1(a: i32, b: i32) -> i32 { |
| 1168 | 1202 | return foo(a, b); |
| 1169 | 1203 | } |
| 1204 | ||
| 1205 | export fn entry() -> usize { @sizeOf(@typeOf(test1)) } | |
| 1170 | 1206 | )SOURCE", 1, ".tmp_source.zig:4:16: error: unable to evaluate constant expression"); |
| 1171 | 1207 | |
| 1172 | 1208 | add_compile_fail_case("goto jumping into block", R"SOURCE( |
| 1173 | fn f() { | |
| 1209 | export fn f() { | |
| 1174 | 1210 | { |
| 1175 | 1211 | a_label: |
| 1176 | 1212 | } |
| ... | ... | @@ -1185,15 +1221,19 @@ fn f(b: bool) { |
| 1185 | 1221 | label: |
| 1186 | 1222 | } |
| 1187 | 1223 | fn derp(){} |
| 1224 | ||
| 1225 | export fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 1188 | 1226 | )SOURCE", 1, ".tmp_source.zig:3:12: error: no label in scope named 'label'"); |
| 1189 | 1227 | |
| 1190 | 1228 | add_compile_fail_case("assign null to non-nullable pointer", R"SOURCE( |
| 1191 | 1229 | const a: &u8 = null; |
| 1230 | ||
| 1231 | export fn entry() -> usize { @sizeOf(@typeOf(a)) } | |
| 1192 | 1232 | )SOURCE", 1, ".tmp_source.zig:2:16: error: expected type '&u8', found '(null)'"); |
| 1193 | 1233 | |
| 1194 | 1234 | add_compile_fail_case("indexing an array of size zero", R"SOURCE( |
| 1195 | 1235 | const array = []u8{}; |
| 1196 | fn foo() { | |
| 1236 | export fn foo() { | |
| 1197 | 1237 | const pointer = &array[0]; |
| 1198 | 1238 | } |
| 1199 | 1239 | )SOURCE", 1, ".tmp_source.zig:4:27: error: index 0 outside array of size 0"); |
| ... | ... | @@ -1203,12 +1243,16 @@ const y = foo(0); |
| 1203 | 1243 | fn foo(x: i32) -> i32 { |
| 1204 | 1244 | 1 / x |
| 1205 | 1245 | } |
| 1246 | ||
| 1247 | export fn entry() -> usize { @sizeOf(@typeOf(y)) } | |
| 1206 | 1248 | )SOURCE", 2, |
| 1207 | 1249 | ".tmp_source.zig:4:7: error: division by zero is undefined", |
| 1208 | 1250 | ".tmp_source.zig:2:14: note: called from here"); |
| 1209 | 1251 | |
| 1210 | 1252 | add_compile_fail_case("branch on undefined value", R"SOURCE( |
| 1211 | 1253 | const x = if (undefined) true else false; |
| 1254 | ||
| 1255 | export fn entry() -> usize { @sizeOf(@typeOf(x)) } | |
| 1212 | 1256 | )SOURCE", 1, ".tmp_source.zig:2:15: error: use of undefined value"); |
| 1213 | 1257 | |
| 1214 | 1258 | |
| ... | ... | @@ -1217,12 +1261,16 @@ const seventh_fib_number = fibbonaci(7); |
| 1217 | 1261 | fn fibbonaci(x: i32) -> i32 { |
| 1218 | 1262 | return fibbonaci(x - 1) + fibbonaci(x - 2); |
| 1219 | 1263 | } |
| 1264 | ||
| 1265 | export fn entry() -> usize { @sizeOf(@typeOf(seventh_fib_number)) } | |
| 1220 | 1266 | )SOURCE", 2, |
| 1221 | 1267 | ".tmp_source.zig:4:21: error: evaluation exceeded 1000 backwards branches", |
| 1222 | 1268 | ".tmp_source.zig:4:21: note: called from here"); |
| 1223 | 1269 | |
| 1224 | 1270 | add_compile_fail_case("@embedFile with bogus file", R"SOURCE( |
| 1225 | 1271 | const resource = @embedFile("bogus.txt"); |
| 1272 | ||
| 1273 | export fn entry() -> usize { @sizeOf(@typeOf(resource)) } | |
| 1226 | 1274 | )SOURCE", 1, ".tmp_source.zig:2:29: error: unable to find './bogus.txt'"); |
| 1227 | 1275 | |
| 1228 | 1276 | |
| ... | ... | @@ -1232,6 +1280,8 @@ const Foo = struct { |
| 1232 | 1280 | }; |
| 1233 | 1281 | const a = Foo {.x = get_it()}; |
| 1234 | 1282 | extern fn get_it() -> i32; |
| 1283 | ||
| 1284 | export fn entry() -> usize { @sizeOf(@typeOf(a)) } | |
| 1235 | 1285 | )SOURCE", 1, ".tmp_source.zig:5:21: error: unable to evaluate constant expression"); |
| 1236 | 1286 | |
| 1237 | 1287 | add_compile_fail_case("non-const expression function call with struct return value outside function", R"SOURCE( |
| ... | ... | @@ -1245,12 +1295,13 @@ fn get_it() -> Foo { |
| 1245 | 1295 | } |
| 1246 | 1296 | var global_side_effect = false; |
| 1247 | 1297 | |
| 1298 | export fn entry() -> usize { @sizeOf(@typeOf(a)) } | |
| 1248 | 1299 | )SOURCE", 2, |
| 1249 | 1300 | ".tmp_source.zig:7:24: error: unable to evaluate constant expression", |
| 1250 | 1301 | ".tmp_source.zig:5:17: note: called from here"); |
| 1251 | 1302 | |
| 1252 | 1303 | add_compile_fail_case("undeclared identifier error should mark fn as impure", R"SOURCE( |
| 1253 | fn foo() { | |
| 1304 | export fn foo() { | |
| 1254 | 1305 | test_a_thing(); |
| 1255 | 1306 | } |
| 1256 | 1307 | fn test_a_thing() { |
| ... | ... | @@ -1269,12 +1320,15 @@ const EnumWithData = enum { |
| 1269 | 1320 | fn bad_eql_2(a: EnumWithData, b: EnumWithData) -> bool { |
| 1270 | 1321 | a == b |
| 1271 | 1322 | } |
| 1323 | ||
| 1324 | export fn entry1() -> usize { @sizeOf(@typeOf(bad_eql_1)) } | |
| 1325 | export fn entry2() -> usize { @sizeOf(@typeOf(bad_eql_2)) } | |
| 1272 | 1326 | )SOURCE", 2, |
| 1273 | 1327 | ".tmp_source.zig:3:7: error: operator not allowed for type '[]u8'", |
| 1274 | 1328 | ".tmp_source.zig:10:7: error: operator not allowed for type 'EnumWithData'"); |
| 1275 | 1329 | |
| 1276 | 1330 | add_compile_fail_case("non-const switch number literal", R"SOURCE( |
| 1277 | fn foo() { | |
| 1331 | export fn foo() { | |
| 1278 | 1332 | const x = switch (bar()) { |
| 1279 | 1333 | 1, 2 => 1, |
| 1280 | 1334 | 3, 4 => 2, |
| ... | ... | @@ -1284,18 +1338,17 @@ fn foo() { |
| 1284 | 1338 | fn bar() -> i32 { |
| 1285 | 1339 | 2 |
| 1286 | 1340 | } |
| 1287 | ||
| 1288 | 1341 | )SOURCE", 1, ".tmp_source.zig:3:15: error: unable to infer expression type"); |
| 1289 | 1342 | |
| 1290 | 1343 | add_compile_fail_case("atomic orderings of cmpxchg - failure stricter than success", R"SOURCE( |
| 1291 | fn f() { | |
| 1344 | export fn f() { | |
| 1292 | 1345 | var x: i32 = 1234; |
| 1293 | 1346 | while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.Monotonic, AtomicOrder.SeqCst)) {} |
| 1294 | 1347 | } |
| 1295 | 1348 | )SOURCE", 1, ".tmp_source.zig:4:72: error: failure atomic ordering must be no stricter than success"); |
| 1296 | 1349 | |
| 1297 | 1350 | add_compile_fail_case("atomic orderings of cmpxchg - success Monotonic or stricter", R"SOURCE( |
| 1298 | fn f() { | |
| 1351 | export fn f() { | |
| 1299 | 1352 | var x: i32 = 1234; |
| 1300 | 1353 | while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.Unordered, AtomicOrder.Unordered)) {} |
| 1301 | 1354 | } |
| ... | ... | @@ -1306,6 +1359,8 @@ const y = neg(-128); |
| 1306 | 1359 | fn neg(x: i8) -> i8 { |
| 1307 | 1360 | -x |
| 1308 | 1361 | } |
| 1362 | ||
| 1363 | export fn entry() -> usize { @sizeOf(@typeOf(y)) } | |
| 1309 | 1364 | )SOURCE", 2, |
| 1310 | 1365 | ".tmp_source.zig:4:5: error: negation caused overflow", |
| 1311 | 1366 | ".tmp_source.zig:2:14: note: called from here"); |
| ... | ... | @@ -1315,6 +1370,8 @@ const y = add(65530, 10); |
| 1315 | 1370 | fn add(a: u16, b: u16) -> u16 { |
| 1316 | 1371 | a + b |
| 1317 | 1372 | } |
| 1373 | ||
| 1374 | export fn entry() -> usize { @sizeOf(@typeOf(y)) } | |
| 1318 | 1375 | )SOURCE", 2, |
| 1319 | 1376 | ".tmp_source.zig:4:7: error: operation caused overflow", |
| 1320 | 1377 | ".tmp_source.zig:2:14: note: called from here"); |
| ... | ... | @@ -1325,6 +1382,8 @@ const y = sub(10, 20); |
| 1325 | 1382 | fn sub(a: u16, b: u16) -> u16 { |
| 1326 | 1383 | a - b |
| 1327 | 1384 | } |
| 1385 | ||
| 1386 | export fn entry() -> usize { @sizeOf(@typeOf(y)) } | |
| 1328 | 1387 | )SOURCE", 2, |
| 1329 | 1388 | ".tmp_source.zig:4:7: error: operation caused overflow", |
| 1330 | 1389 | ".tmp_source.zig:2:14: note: called from here"); |
| ... | ... | @@ -1334,6 +1393,8 @@ const y = mul(300, 6000); |
| 1334 | 1393 | fn mul(a: u16, b: u16) -> u16 { |
| 1335 | 1394 | a * b |
| 1336 | 1395 | } |
| 1396 | ||
| 1397 | export fn entry() -> usize { @sizeOf(@typeOf(y)) } | |
| 1337 | 1398 | )SOURCE", 2, |
| 1338 | 1399 | ".tmp_source.zig:4:7: error: operation caused overflow", |
| 1339 | 1400 | ".tmp_source.zig:2:14: note: called from here"); |
| ... | ... | @@ -1343,10 +1404,12 @@ fn f() -> i8 { |
| 1343 | 1404 | const x: u32 = 10; |
| 1344 | 1405 | @truncate(i8, x) |
| 1345 | 1406 | } |
| 1407 | ||
| 1408 | export fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 1346 | 1409 | )SOURCE", 1, ".tmp_source.zig:4:19: error: expected signed integer type, found 'u32'"); |
| 1347 | 1410 | |
| 1348 | 1411 | add_compile_fail_case("%return in function with non error return type", R"SOURCE( |
| 1349 | fn f() { | |
| 1412 | export fn f() { | |
| 1350 | 1413 | %return something(); |
| 1351 | 1414 | } |
| 1352 | 1415 | fn something() -> %void { } |
| ... | ... | @@ -1361,7 +1424,7 @@ pub fn main(args: [][]u8) { } |
| 1361 | 1424 | add_compile_fail_case("invalid pointer for var type", R"SOURCE( |
| 1362 | 1425 | extern fn ext() -> usize; |
| 1363 | 1426 | var bytes: [ext()]u8 = undefined; |
| 1364 | fn f() { | |
| 1427 | export fn f() { | |
| 1365 | 1428 | for (bytes) |*b, i| { |
| 1366 | 1429 | *b = u8(i); |
| 1367 | 1430 | } |
| ... | ... | @@ -1379,10 +1442,11 @@ extern fn foo(comptime x: i32, y: i32) -> i32; |
| 1379 | 1442 | fn f() -> i32 { |
| 1380 | 1443 | foo(1, 2) |
| 1381 | 1444 | } |
| 1445 | export fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 1382 | 1446 | )SOURCE", 1, ".tmp_source.zig:2:15: error: comptime parameter not allowed in extern function"); |
| 1383 | 1447 | |
| 1384 | 1448 | add_compile_fail_case("convert fixed size array to slice with invalid size", R"SOURCE( |
| 1385 | fn f() { | |
| 1449 | export fn f() { | |
| 1386 | 1450 | var array: [5]u8 = undefined; |
| 1387 | 1451 | var foo = ([]const u32)(array)[0]; |
| 1388 | 1452 | } |
| ... | ... | @@ -1403,7 +1467,7 @@ pub fn SmallList(comptime T: type, comptime STATIC_SIZE: usize) -> type { |
| 1403 | 1467 | } |
| 1404 | 1468 | } |
| 1405 | 1469 | |
| 1406 | fn function_with_return_type_type() { | |
| 1470 | export fn function_with_return_type_type() { | |
| 1407 | 1471 | var list: List(i32) = undefined; |
| 1408 | 1472 | list.length = 10; |
| 1409 | 1473 | } |
| ... | ... | @@ -1417,6 +1481,7 @@ var self = "aoeu"; |
| 1417 | 1481 | fn f(m: []const u8) { |
| 1418 | 1482 | m.copy(u8, self[0...], m); |
| 1419 | 1483 | } |
| 1484 | export fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 1420 | 1485 | )SOURCE", 1, ".tmp_source.zig:4:6: error: no member named 'copy' in '[]const u8'"); |
| 1421 | 1486 | |
| 1422 | 1487 | add_compile_fail_case("wrong number of arguments for method fn call", R"SOURCE( |
| ... | ... | @@ -1427,17 +1492,18 @@ fn f(foo: &const Foo) { |
| 1427 | 1492 | |
| 1428 | 1493 | foo.method(1, 2); |
| 1429 | 1494 | } |
| 1495 | export fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 1430 | 1496 | )SOURCE", 1, ".tmp_source.zig:7:15: error: expected 2 arguments, found 3"); |
| 1431 | 1497 | |
| 1432 | 1498 | add_compile_fail_case("assign through constant pointer", R"SOURCE( |
| 1433 | fn f() { | |
| 1499 | export fn f() { | |
| 1434 | 1500 | var cstr = c"Hat"; |
| 1435 | 1501 | cstr[0] = 'W'; |
| 1436 | 1502 | } |
| 1437 | 1503 | )SOURCE", 1, ".tmp_source.zig:4:11: error: cannot assign to constant"); |
| 1438 | 1504 | |
| 1439 | 1505 | add_compile_fail_case("assign through constant slice", R"SOURCE( |
| 1440 | pub fn f() { | |
| 1506 | export fn f() { | |
| 1441 | 1507 | var cstr: []const u8 = "Hat"; |
| 1442 | 1508 | cstr[0] = 'W'; |
| 1443 | 1509 | } |
| ... | ... | @@ -1451,6 +1517,7 @@ pub fn main(args: [][]bogus) -> %void {} |
| 1451 | 1517 | fn foo(blah: []u8) { |
| 1452 | 1518 | for (blah) { } |
| 1453 | 1519 | } |
| 1520 | export fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 1454 | 1521 | )SOURCE", 1, ".tmp_source.zig:3:5: error: for loop expression missing element parameter"); |
| 1455 | 1522 | |
| 1456 | 1523 | add_compile_fail_case("misspelled type with pointer only reference", R"SOURCE( |
| ... | ... | @@ -1482,6 +1549,8 @@ fn foo() { |
| 1482 | 1549 | jll.init(1234); |
| 1483 | 1550 | var jd = JsonNode {.kind = JsonType.JSONArray , .jobject = JsonOA.JSONArray {jll} }; |
| 1484 | 1551 | } |
| 1552 | ||
| 1553 | export fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 1485 | 1554 | )SOURCE", 1, ".tmp_source.zig:6:16: error: use of undeclared identifier 'JsonList'"); |
| 1486 | 1555 | |
| 1487 | 1556 | add_compile_fail_case("method call with first arg type primitive", R"SOURCE( |
| ... | ... | @@ -1495,7 +1564,7 @@ const Foo = struct { |
| 1495 | 1564 | } |
| 1496 | 1565 | }; |
| 1497 | 1566 | |
| 1498 | fn f() { | |
| 1567 | export fn f() { | |
| 1499 | 1568 | const derp = Foo.init(3); |
| 1500 | 1569 | |
| 1501 | 1570 | derp.init(); |
| ... | ... | @@ -1523,7 +1592,7 @@ pub const Allocator = struct { |
| 1523 | 1592 | field: i32, |
| 1524 | 1593 | }; |
| 1525 | 1594 | |
| 1526 | fn foo() { | |
| 1595 | export fn foo() { | |
| 1527 | 1596 | var x = List.init(&global_allocator); |
| 1528 | 1597 | x.init(); |
| 1529 | 1598 | } |
| ... | ... | @@ -1533,13 +1602,15 @@ fn foo() { |
| 1533 | 1602 | const TINY_QUANTUM_SHIFT = 4; |
| 1534 | 1603 | const TINY_QUANTUM_SIZE = 1 << TINY_QUANTUM_SHIFT; |
| 1535 | 1604 | var block_aligned_stuff: usize = (4 + TINY_QUANTUM_SIZE) & ~(TINY_QUANTUM_SIZE - 1); |
| 1605 | ||
| 1606 | export fn entry() -> usize { @sizeOf(@typeOf(block_aligned_stuff)) } | |
| 1536 | 1607 | )SOURCE", 1, ".tmp_source.zig:4:60: error: unable to perform binary not operation on type '(integer literal)'"); |
| 1537 | 1608 | |
| 1538 | 1609 | { |
| 1539 | 1610 | TestCase *tc = add_compile_fail_case("multiple files with private function error", R"SOURCE( |
| 1540 | 1611 | const foo = @import("foo.zig"); |
| 1541 | 1612 | |
| 1542 | fn callPrivFunction() { | |
| 1613 | export fn callPrivFunction() { | |
| 1543 | 1614 | foo.privateFunction(); |
| 1544 | 1615 | } |
| 1545 | 1616 | )SOURCE", 2, |
| ... | ... | @@ -1554,13 +1625,15 @@ fn privateFunction() { } |
| 1554 | 1625 | add_compile_fail_case("container init with non-type", R"SOURCE( |
| 1555 | 1626 | const zero: i32 = 0; |
| 1556 | 1627 | const a = zero{1}; |
| 1628 | ||
| 1629 | export fn entry() -> usize { @sizeOf(@typeOf(a)) } | |
| 1557 | 1630 | )SOURCE", 1, ".tmp_source.zig:3:11: error: expected type, found 'i32'"); |
| 1558 | 1631 | |
| 1559 | 1632 | add_compile_fail_case("assign to constant field", R"SOURCE( |
| 1560 | 1633 | const Foo = struct { |
| 1561 | 1634 | field: i32, |
| 1562 | 1635 | }; |
| 1563 | fn derp() { | |
| 1636 | export fn derp() { | |
| 1564 | 1637 | const f = Foo {.field = 1234,}; |
| 1565 | 1638 | f.field = 0; |
| 1566 | 1639 | } |
| ... | ... | @@ -1580,6 +1653,8 @@ fn canFail() -> %void { } |
| 1580 | 1653 | pub fn maybeInt() -> ?i32 { |
| 1581 | 1654 | return 0; |
| 1582 | 1655 | } |
| 1656 | ||
| 1657 | export fn entry() -> usize { @sizeOf(@typeOf(testTrickyDefer)) } | |
| 1583 | 1658 | )SOURCE", 1, ".tmp_source.zig:5:11: error: cannot return from defer expression"); |
| 1584 | 1659 | |
| 1585 | 1660 | add_compile_fail_case("attempt to access var args out of bounds", R"SOURCE( |
| ... | ... | @@ -1590,6 +1665,8 @@ fn add(args: ...) -> i32 { |
| 1590 | 1665 | fn foo() -> i32 { |
| 1591 | 1666 | add(i32(1234)) |
| 1592 | 1667 | } |
| 1668 | ||
| 1669 | export fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 1593 | 1670 | )SOURCE", 2, |
| 1594 | 1671 | ".tmp_source.zig:3:19: error: index 1 outside argument list of size 1", |
| 1595 | 1672 | ".tmp_source.zig:7:8: note: called from here"); |
| ... | ... | @@ -1606,10 +1683,12 @@ fn add(args: ...) -> i32 { |
| 1606 | 1683 | fn bar() -> i32 { |
| 1607 | 1684 | add(1, 2, 3, 4) |
| 1608 | 1685 | } |
| 1686 | ||
| 1687 | export fn entry() -> usize { @sizeOf(@typeOf(bar)) } | |
| 1609 | 1688 | )SOURCE", 1, ".tmp_source.zig:11:9: error: parameter of type '(integer literal)' requires comptime"); |
| 1610 | 1689 | |
| 1611 | 1690 | add_compile_fail_case("assign too big number to u16", R"SOURCE( |
| 1612 | fn foo() { | |
| 1691 | export fn foo() { | |
| 1613 | 1692 | var vga_mem: u16 = 0xB8000; |
| 1614 | 1693 | } |
| 1615 | 1694 | )SOURCE", 1, ".tmp_source.zig:3:24: error: integer value 753664 cannot be implicitly casted to type 'u16'"); |
| ... | ... | @@ -1619,10 +1698,11 @@ const some_data: [100]u8 = { |
| 1619 | 1698 | @setGlobalAlign(some_data, 3); |
| 1620 | 1699 | undefined |
| 1621 | 1700 | }; |
| 1701 | export fn entry() -> usize { @sizeOf(@typeOf(some_data)) } | |
| 1622 | 1702 | )SOURCE", 1, ".tmp_source.zig:3:32: error: alignment value must be power of 2"); |
| 1623 | 1703 | |
| 1624 | 1704 | add_compile_fail_case("compile log", R"SOURCE( |
| 1625 | fn foo() { | |
| 1705 | export fn foo() { | |
| 1626 | 1706 | comptime bar(12, "hi"); |
| 1627 | 1707 | } |
| 1628 | 1708 | fn bar(a: i32, b: []const u8) { |
| ... | ... | @@ -1660,9 +1740,11 @@ fn foo(bit_field: &const BitField) -> u3 { |
| 1660 | 1740 | fn bar(x: &const u3) -> u3 { |
| 1661 | 1741 | return *x; |
| 1662 | 1742 | } |
| 1743 | ||
| 1744 | export fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 1663 | 1745 | )SOURCE", 1, ".tmp_source.zig:12:26: error: expected type '&const u3', found '&:3:6 const u3'"); |
| 1664 | 1746 | |
| 1665 | add_compile_fail_case_no_check_unused("referring to a struct that is invalid without --check-unused", R"SOURCE( | |
| 1747 | add_compile_fail_case("referring to a struct that is invalid", R"SOURCE( | |
| 1666 | 1748 | const UsbDeviceRequest = struct { |
| 1667 | 1749 | Type: u8, |
| 1668 | 1750 | }; |
| ... | ... | @@ -1679,7 +1761,7 @@ fn assert(ok: bool) { |
| 1679 | 1761 | ".tmp_source.zig:7:20: note: called from here"); |
| 1680 | 1762 | |
| 1681 | 1763 | add_compile_fail_case("control flow uses comptime var at runtime", R"SOURCE( |
| 1682 | fn foo() { | |
| 1764 | export fn foo() { | |
| 1683 | 1765 | comptime var i = 0; |
| 1684 | 1766 | while (i < 5; i += 1) { |
| 1685 | 1767 | bar(); |
| ... | ... | @@ -1692,14 +1774,14 @@ fn bar() { } |
| 1692 | 1774 | ".tmp_source.zig:4:21: note: compile-time variable assigned here"); |
| 1693 | 1775 | |
| 1694 | 1776 | add_compile_fail_case("ignored return value", R"SOURCE( |
| 1695 | fn foo() { | |
| 1777 | export fn foo() { | |
| 1696 | 1778 | bar(); |
| 1697 | 1779 | } |
| 1698 | 1780 | fn bar() -> i32 { 0 } |
| 1699 | 1781 | )SOURCE", 1, ".tmp_source.zig:3:8: error: return value ignored"); |
| 1700 | 1782 | |
| 1701 | 1783 | add_compile_fail_case("integer literal on a non-comptime var", R"SOURCE( |
| 1702 | fn foo() { | |
| 1784 | export fn foo() { | |
| 1703 | 1785 | var i = 0; |
| 1704 | 1786 | while (i < 10; i += 1) { } |
| 1705 | 1787 | } |
| ... | ... | @@ -1712,6 +1794,8 @@ pub fn pass(in: []u8) -> []u8 { |
| 1712 | 1794 | *out[0] = in[0]; |
| 1713 | 1795 | return (*out)[0...1]; |
| 1714 | 1796 | } |
| 1797 | ||
| 1798 | export fn entry() -> usize { @sizeOf(@typeOf(pass)) } | |
| 1715 | 1799 | )SOURCE", 1, ".tmp_source.zig:5:5: error: attempt to dereference non pointer type '[10]u8'"); |
| 1716 | 1800 | |
| 1717 | 1801 | add_compile_fail_case("pass const ptr to mutable ptr fn", R"SOURCE( |
| ... | ... | @@ -1723,6 +1807,8 @@ fn foo() -> bool { |
| 1723 | 1807 | fn ptrEql(a: &[]const u8, b: &[]const u8) -> bool { |
| 1724 | 1808 | return true; |
| 1725 | 1809 | } |
| 1810 | ||
| 1811 | export fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 1726 | 1812 | )SOURCE", 1, ".tmp_source.zig:5:19: error: expected type '&[]const u8', found '&const []const u8'"); |
| 1727 | 1813 | } |
| 1728 | 1814 | |
| ... | ... | @@ -2159,23 +2245,69 @@ static void run_self_hosted_test(bool is_release_mode) { |
| 2159 | 2245 | } |
| 2160 | 2246 | } |
| 2161 | 2247 | |
| 2248 | static void run_std_lib_test(bool is_release_mode) { | |
| 2249 | Buf std_index_file = BUF_INIT; | |
| 2250 | os_path_join(buf_create_from_str(ZIG_STD_DIR), | |
| 2251 | buf_create_from_str("index.zig"), &std_index_file); | |
| 2252 | ||
| 2253 | Buf zig_stderr = BUF_INIT; | |
| 2254 | Buf zig_stdout = BUF_INIT; | |
| 2255 | ZigList<const char *> args = {0}; | |
| 2256 | args.append("test"); | |
| 2257 | args.append(buf_ptr(&std_index_file)); | |
| 2258 | if (is_release_mode) { | |
| 2259 | args.append("--release"); | |
| 2260 | } | |
| 2261 | Termination term; | |
| 2262 | os_exec_process(zig_exe, args, &term, &zig_stderr, &zig_stdout); | |
| 2263 | ||
| 2264 | if (term.how != TerminationIdClean || term.code != 0) { | |
| 2265 | printf("\nstd lib tests failed:\n"); | |
| 2266 | printf("./zig"); | |
| 2267 | for (size_t i = 0; i < args.length; i += 1) { | |
| 2268 | printf(" %s", args.at(i)); | |
| 2269 | } | |
| 2270 | printf("\n%s\n", buf_ptr(&zig_stderr)); | |
| 2271 | exit(1); | |
| 2272 | } | |
| 2273 | } | |
| 2274 | ||
| 2275 | ||
| 2162 | 2276 | static void add_self_hosted_tests(void) { |
| 2163 | 2277 | { |
| 2164 | 2278 | TestCase *test_case = allocate<TestCase>(1); |
| 2165 | 2279 | test_case->case_name = "self hosted tests (debug)"; |
| 2166 | test_case->is_self_hosted = true; | |
| 2280 | test_case->special = TestSpecialSelfHosted; | |
| 2167 | 2281 | test_case->is_release_mode = false; |
| 2168 | 2282 | test_cases.append(test_case); |
| 2169 | 2283 | } |
| 2170 | 2284 | { |
| 2171 | 2285 | TestCase *test_case = allocate<TestCase>(1); |
| 2172 | 2286 | test_case->case_name = "self hosted tests (release)"; |
| 2173 | test_case->is_self_hosted = true; | |
| 2287 | test_case->special = TestSpecialSelfHosted; | |
| 2174 | 2288 | test_case->is_release_mode = true; |
| 2175 | 2289 | test_cases.append(test_case); |
| 2176 | 2290 | } |
| 2177 | 2291 | } |
| 2178 | 2292 | |
| 2293 | static void add_std_lib_tests(void) { | |
| 2294 | { | |
| 2295 | TestCase *test_case = allocate<TestCase>(1); | |
| 2296 | test_case->case_name = "std (debug)"; | |
| 2297 | test_case->special = TestSpecialStd; | |
| 2298 | test_case->is_release_mode = false; | |
| 2299 | test_cases.append(test_case); | |
| 2300 | } | |
| 2301 | { | |
| 2302 | TestCase *test_case = allocate<TestCase>(1); | |
| 2303 | test_case->case_name = "std (release)"; | |
| 2304 | test_case->special = TestSpecialStd; | |
| 2305 | test_case->is_release_mode = true; | |
| 2306 | test_cases.append(test_case); | |
| 2307 | } | |
| 2308 | } | |
| 2309 | ||
| 2310 | ||
| 2179 | 2311 | static void print_compiler_invocation(TestCase *test_case) { |
| 2180 | 2312 | printf("%s", zig_exe); |
| 2181 | 2313 | for (size_t i = 0; i < test_case->compiler_args.length; i += 1) { |
| ... | ... | @@ -2193,8 +2325,10 @@ static void print_exe_invocation(TestCase *test_case) { |
| 2193 | 2325 | } |
| 2194 | 2326 | |
| 2195 | 2327 | static void run_test(TestCase *test_case) { |
| 2196 | if (test_case->is_self_hosted) { | |
| 2328 | if (test_case->special == TestSpecialSelfHosted) { | |
| 2197 | 2329 | return run_self_hosted_test(test_case->is_release_mode); |
| 2330 | } else if (test_case->special == TestSpecialStd) { | |
| 2331 | return run_std_lib_test(test_case->is_release_mode); | |
| 2198 | 2332 | } |
| 2199 | 2333 | |
| 2200 | 2334 | for (size_t i = 0; i < test_case->source_files.length; i += 1) { |
| ... | ... | @@ -2366,6 +2500,7 @@ int main(int argc, char **argv) { |
| 2366 | 2500 | add_compile_failure_test_cases(); |
| 2367 | 2501 | add_parseh_test_cases(); |
| 2368 | 2502 | add_self_hosted_tests(); |
| 2503 | add_std_lib_tests(); | |
| 2369 | 2504 | run_all_tests(reverse); |
| 2370 | 2505 | cleanup(); |
| 2371 | 2506 | } |