mirror of
https://github.com/ziglang/zig.git
synced 2024-11-15 08:33:06 +00:00
introduce new test syntax
* remove setFnTest builtin * add test "name" { ... } syntax * remove --check-unused argument. functions are always lazy now.
This commit is contained in:
parent
329457bb4f
commit
af536ac343
@ -5,7 +5,9 @@
|
||||
```
|
||||
Root = many(TopLevelItem) "EOF"
|
||||
|
||||
TopLevelItem = ErrorValueDecl | Block | TopLevelDecl
|
||||
TopLevelItem = ErrorValueDecl | Block | TopLevelDecl | TestDecl
|
||||
|
||||
TestDecl = "test" String Block
|
||||
|
||||
TopLevelDecl = option(VisibleMod) (FnDef | ExternDecl | GlobalVarDecl | TypeDecl | UseDecl)
|
||||
|
||||
|
@ -15,7 +15,7 @@ syn keyword zigConditional if else switch try
|
||||
syn keyword zigRepeat while for
|
||||
|
||||
syn keyword zigConstant null undefined this
|
||||
syn keyword zigKeyword fn use
|
||||
syn keyword zigKeyword fn use test
|
||||
syn keyword zigType bool f32 f64 void Unreachable type error
|
||||
syn keyword zigType i8 u8 i16 u16 i32 u32 i64 u64 isize usize
|
||||
syn keyword zigType c_short c_ushort c_int c_uint c_long c_ulong c_longlong c_ulonglong c_long_double
|
||||
|
@ -311,6 +311,7 @@ enum NodeType {
|
||||
NodeTypeVariableDeclaration,
|
||||
NodeTypeTypeDecl,
|
||||
NodeTypeErrorValueDecl,
|
||||
NodeTypeTestDecl,
|
||||
NodeTypeBinOpExpr,
|
||||
NodeTypeUnwrapErrorExpr,
|
||||
NodeTypeNumberLiteral,
|
||||
@ -435,6 +436,14 @@ struct AstNodeErrorValueDecl {
|
||||
ErrorTableEntry *err;
|
||||
};
|
||||
|
||||
struct AstNodeTestDecl {
|
||||
// always invalid if it's not VisibModPrivate but can be parsed that way
|
||||
VisibMod visib_mod;
|
||||
Buf *name;
|
||||
|
||||
AstNode *body;
|
||||
};
|
||||
|
||||
enum BinOpType {
|
||||
BinOpTypeInvalid,
|
||||
BinOpTypeAssign,
|
||||
@ -781,6 +790,7 @@ struct AstNode {
|
||||
AstNodeVariableDeclaration variable_declaration;
|
||||
AstNodeTypeDecl type_decl;
|
||||
AstNodeErrorValueDecl error_value_decl;
|
||||
AstNodeTestDecl test_decl;
|
||||
AstNodeBinOpExpr bin_op_expr;
|
||||
AstNodeUnwrapErrorExpr unwrap_err_expr;
|
||||
AstNodePrefixOpExpr prefix_op_expr;
|
||||
@ -1091,7 +1101,7 @@ enum FnInline {
|
||||
struct FnTableEntry {
|
||||
LLVMValueRef llvm_value;
|
||||
AstNode *proto_node;
|
||||
AstNode *fn_def_node;
|
||||
AstNode *body_node;
|
||||
ScopeFnDef *fndef_scope; // parent should be the top level decls or container decls
|
||||
Scope *child_scope; // parent is scope for last parameter
|
||||
ScopeBlock *def_scope; // parent is child_scope
|
||||
@ -1161,7 +1171,6 @@ enum BuiltinFnId {
|
||||
BuiltinFnIdTruncate,
|
||||
BuiltinFnIdIntType,
|
||||
BuiltinFnIdUnreachable,
|
||||
BuiltinFnIdSetFnTest,
|
||||
BuiltinFnIdSetFnVisible,
|
||||
BuiltinFnIdSetDebugSafety,
|
||||
BuiltinFnIdAlloca,
|
||||
@ -1411,8 +1420,8 @@ struct CodeGen {
|
||||
ZigList<const char *> lib_dirs;
|
||||
|
||||
uint32_t test_fn_count;
|
||||
TypeTableEntry *test_fn_type;
|
||||
|
||||
bool check_unused;
|
||||
bool each_lib_rpath;
|
||||
|
||||
ZigList<AstNode *> error_decls;
|
||||
@ -1630,7 +1639,6 @@ enum IrInstructionId {
|
||||
IrInstructionIdTypeOf,
|
||||
IrInstructionIdToPtrType,
|
||||
IrInstructionIdPtrTypeChild,
|
||||
IrInstructionIdSetFnTest,
|
||||
IrInstructionIdSetFnVisible,
|
||||
IrInstructionIdSetDebugSafety,
|
||||
IrInstructionIdArrayType,
|
||||
@ -1973,12 +1981,6 @@ struct IrInstructionPtrTypeChild {
|
||||
IrInstruction *value;
|
||||
};
|
||||
|
||||
struct IrInstructionSetFnTest {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *fn_value;
|
||||
};
|
||||
|
||||
struct IrInstructionSetFnVisible {
|
||||
IrInstruction base;
|
||||
|
||||
|
174
src/analyze.cpp
174
src/analyze.cpp
@ -130,7 +130,6 @@ Scope *create_loop_scope(AstNode *node, Scope *parent) {
|
||||
}
|
||||
|
||||
ScopeFnDef *create_fndef_scope(AstNode *node, Scope *parent, FnTableEntry *fn_entry) {
|
||||
assert(!node || node->type == NodeTypeFnDef);
|
||||
ScopeFnDef *scope = allocate<ScopeFnDef>(1);
|
||||
init_scope(&scope->base, ScopeIdFnDef, node, parent);
|
||||
scope->fn_entry = fn_entry;
|
||||
@ -1756,7 +1755,8 @@ FnTableEntry *create_fn(AstNode *proto_node) {
|
||||
FnTableEntry *fn_entry = create_fn_raw(inline_value, internal_linkage);
|
||||
|
||||
fn_entry->proto_node = proto_node;
|
||||
fn_entry->fn_def_node = proto_node->data.fn_proto.fn_def_node;
|
||||
fn_entry->body_node = (proto_node->data.fn_proto.fn_def_node == nullptr) ? nullptr :
|
||||
proto_node->data.fn_proto.fn_def_node->data.fn_def.body;
|
||||
|
||||
return fn_entry;
|
||||
}
|
||||
@ -1799,76 +1799,107 @@ static void typecheck_panic_fn(CodeGen *g) {
|
||||
}
|
||||
}
|
||||
|
||||
static TypeTableEntry *get_test_fn_type(CodeGen *g) {
|
||||
if (g->test_fn_type)
|
||||
return g->test_fn_type;
|
||||
|
||||
FnTypeId fn_type_id = {0};
|
||||
fn_type_id.return_type = g->builtin_types.entry_void;
|
||||
g->test_fn_type = get_fn_type(g, &fn_type_id);
|
||||
return g->test_fn_type;
|
||||
}
|
||||
|
||||
static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
|
||||
ImportTableEntry *import = tld_fn->base.import;
|
||||
AstNode *proto_node = tld_fn->base.source_node;
|
||||
assert(proto_node->type == NodeTypeFnProto);
|
||||
AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;
|
||||
AstNode *source_node = tld_fn->base.source_node;
|
||||
if (source_node->type == NodeTypeFnProto) {
|
||||
AstNodeFnProto *fn_proto = &source_node->data.fn_proto;
|
||||
|
||||
AstNode *fn_def_node = fn_proto->fn_def_node;
|
||||
AstNode *fn_def_node = fn_proto->fn_def_node;
|
||||
|
||||
FnTableEntry *fn_table_entry = create_fn(tld_fn->base.source_node);
|
||||
get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_');
|
||||
FnTableEntry *fn_table_entry = create_fn(source_node);
|
||||
get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_');
|
||||
|
||||
tld_fn->fn_entry = fn_table_entry;
|
||||
tld_fn->fn_entry = fn_table_entry;
|
||||
|
||||
if (fn_table_entry->fn_def_node) {
|
||||
fn_table_entry->fndef_scope = create_fndef_scope(
|
||||
fn_table_entry->fn_def_node, tld_fn->base.parent_scope, fn_table_entry);
|
||||
if (fn_table_entry->body_node) {
|
||||
fn_table_entry->fndef_scope = create_fndef_scope(
|
||||
fn_table_entry->body_node, tld_fn->base.parent_scope, fn_table_entry);
|
||||
|
||||
for (size_t i = 0; i < fn_proto->params.length; i += 1) {
|
||||
AstNode *param_node = fn_proto->params.at(i);
|
||||
assert(param_node->type == NodeTypeParamDecl);
|
||||
if (buf_len(param_node->data.param_decl.name) == 0) {
|
||||
add_node_error(g, param_node, buf_sprintf("missing parameter name"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Scope *child_scope = fn_table_entry->fndef_scope ? &fn_table_entry->fndef_scope->base : tld_fn->base.parent_scope;
|
||||
fn_table_entry->type_entry = analyze_fn_type(g, proto_node, child_scope);
|
||||
|
||||
if (fn_table_entry->type_entry->id == TypeTableEntryIdInvalid) {
|
||||
tld_fn->base.resolution = TldResolutionInvalid;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!fn_table_entry->type_entry->data.fn.is_generic) {
|
||||
g->fn_protos.append(fn_table_entry);
|
||||
|
||||
if (fn_def_node)
|
||||
g->fn_defs.append(fn_table_entry);
|
||||
|
||||
if (import == g->root_import && scope_is_root_decls(tld_fn->base.parent_scope)) {
|
||||
if (buf_eql_str(&fn_table_entry->symbol_name, "main")) {
|
||||
g->main_fn = fn_table_entry;
|
||||
|
||||
if (!g->link_libc && tld_fn->base.visib_mod != VisibModExport) {
|
||||
TypeTableEntry *err_void = get_error_type(g, g->builtin_types.entry_void);
|
||||
TypeTableEntry *actual_return_type = fn_table_entry->type_entry->data.fn.fn_type_id.return_type;
|
||||
if (actual_return_type != err_void) {
|
||||
add_node_error(g, fn_proto->return_type,
|
||||
buf_sprintf("expected return type of main to be '%%void', instead is '%s'",
|
||||
buf_ptr(&actual_return_type->name)));
|
||||
}
|
||||
for (size_t i = 0; i < fn_proto->params.length; i += 1) {
|
||||
AstNode *param_node = fn_proto->params.at(i);
|
||||
assert(param_node->type == NodeTypeParamDecl);
|
||||
if (buf_len(param_node->data.param_decl.name) == 0) {
|
||||
add_node_error(g, param_node, buf_sprintf("missing parameter name"));
|
||||
}
|
||||
} else if (buf_eql_str(&fn_table_entry->symbol_name, "panic")) {
|
||||
g->panic_fn = fn_table_entry;
|
||||
typecheck_panic_fn(g);
|
||||
}
|
||||
} else if (import->package == g->panic_package && scope_is_root_decls(tld_fn->base.parent_scope)) {
|
||||
if (buf_eql_str(&fn_table_entry->symbol_name, "panic")) {
|
||||
g->panic_fn = fn_table_entry;
|
||||
typecheck_panic_fn(g);
|
||||
}
|
||||
}
|
||||
|
||||
Scope *child_scope = fn_table_entry->fndef_scope ? &fn_table_entry->fndef_scope->base : tld_fn->base.parent_scope;
|
||||
fn_table_entry->type_entry = analyze_fn_type(g, source_node, child_scope);
|
||||
|
||||
if (fn_table_entry->type_entry->id == TypeTableEntryIdInvalid) {
|
||||
tld_fn->base.resolution = TldResolutionInvalid;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!fn_table_entry->type_entry->data.fn.is_generic) {
|
||||
g->fn_protos.append(fn_table_entry);
|
||||
|
||||
if (fn_def_node)
|
||||
g->fn_defs.append(fn_table_entry);
|
||||
|
||||
if (import == g->root_import && scope_is_root_decls(tld_fn->base.parent_scope)) {
|
||||
if (buf_eql_str(&fn_table_entry->symbol_name, "main")) {
|
||||
g->main_fn = fn_table_entry;
|
||||
|
||||
if (!g->link_libc && tld_fn->base.visib_mod != VisibModExport) {
|
||||
TypeTableEntry *err_void = get_error_type(g, g->builtin_types.entry_void);
|
||||
TypeTableEntry *actual_return_type = fn_table_entry->type_entry->data.fn.fn_type_id.return_type;
|
||||
if (actual_return_type != err_void) {
|
||||
add_node_error(g, fn_proto->return_type,
|
||||
buf_sprintf("expected return type of main to be '%%void', instead is '%s'",
|
||||
buf_ptr(&actual_return_type->name)));
|
||||
}
|
||||
}
|
||||
} else if (buf_eql_str(&fn_table_entry->symbol_name, "panic")) {
|
||||
g->panic_fn = fn_table_entry;
|
||||
typecheck_panic_fn(g);
|
||||
}
|
||||
} else if (import->package == g->panic_package && scope_is_root_decls(tld_fn->base.parent_scope)) {
|
||||
if (buf_eql_str(&fn_table_entry->symbol_name, "panic")) {
|
||||
g->panic_fn = fn_table_entry;
|
||||
typecheck_panic_fn(g);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (source_node->type == NodeTypeTestDecl) {
|
||||
FnTableEntry *fn_table_entry = create_fn_raw(FnInlineAuto, false);
|
||||
|
||||
get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_');
|
||||
|
||||
tld_fn->fn_entry = fn_table_entry;
|
||||
|
||||
fn_table_entry->proto_node = source_node;
|
||||
fn_table_entry->fndef_scope = create_fndef_scope(source_node, tld_fn->base.parent_scope, fn_table_entry);
|
||||
fn_table_entry->type_entry = get_test_fn_type(g);
|
||||
fn_table_entry->body_node = source_node->data.test_decl.body;
|
||||
fn_table_entry->is_test = true;
|
||||
g->test_fn_count += 1;
|
||||
|
||||
g->fn_protos.append(fn_table_entry);
|
||||
g->fn_defs.append(fn_table_entry);
|
||||
|
||||
} else {
|
||||
zig_unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
|
||||
if (g->check_unused || g->is_test_build || tld->visib_mod == VisibModExport ||
|
||||
if (tld->visib_mod == VisibModExport ||
|
||||
(buf_eql_str(tld->name, "panic") &&
|
||||
(decls_scope->import->package == g->panic_package || decls_scope->import == g->root_import)))
|
||||
(decls_scope->import->package == g->panic_package || decls_scope->import == g->root_import)) ||
|
||||
(tld->id == TldIdVar && g->is_test_build))
|
||||
{
|
||||
g->resolve_queue.append(tld);
|
||||
}
|
||||
@ -1882,6 +1913,27 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
|
||||
}
|
||||
}
|
||||
|
||||
static void preview_test_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {
|
||||
assert(node->type == NodeTypeTestDecl);
|
||||
|
||||
if (node->data.test_decl.visib_mod != VisibModPrivate) {
|
||||
add_node_error(g, node, buf_sprintf("tests require no visibility modifier"));
|
||||
}
|
||||
|
||||
if (!g->is_test_build)
|
||||
return;
|
||||
|
||||
ImportTableEntry *import = get_scope_import(&decls_scope->base);
|
||||
if (import->package != g->root_package)
|
||||
return;
|
||||
|
||||
Buf *test_name = node->data.test_decl.name;
|
||||
|
||||
TldFn *tld_fn = allocate<TldFn>(1);
|
||||
init_tld(&tld_fn->base, TldIdFn, test_name, VisibModPrivate, node, &decls_scope->base);
|
||||
g->resolve_queue.append(&tld_fn->base);
|
||||
}
|
||||
|
||||
static void preview_error_value_decl(CodeGen *g, AstNode *node) {
|
||||
assert(node->type == NodeTypeErrorValueDecl);
|
||||
|
||||
@ -1975,6 +2027,9 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
|
||||
// error value declarations do not depend on other top level decls
|
||||
preview_error_value_decl(g, node);
|
||||
break;
|
||||
case NodeTypeTestDecl:
|
||||
preview_test_decl(g, node, decls_scope);
|
||||
break;
|
||||
case NodeTypeContainerDecl:
|
||||
case NodeTypeParamDecl:
|
||||
case NodeTypeFnDecl:
|
||||
@ -2650,7 +2705,8 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {
|
||||
|
||||
fn_table_entry->anal_state = FnAnalStateProbing;
|
||||
|
||||
AstNode *return_type_node = fn_table_entry->proto_node->data.fn_proto.return_type;
|
||||
AstNode *return_type_node = (fn_table_entry->proto_node != nullptr) ?
|
||||
fn_table_entry->proto_node->data.fn_proto.return_type : fn_table_entry->fndef_scope->base.source_node;
|
||||
|
||||
assert(fn_table_entry->fndef_scope);
|
||||
if (!fn_table_entry->child_scope)
|
||||
@ -2674,7 +2730,7 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {
|
||||
}
|
||||
if (g->verbose) {
|
||||
fprintf(stderr, "\n");
|
||||
ast_render(stderr, fn_table_entry->fn_def_node, 4);
|
||||
ast_render(stderr, fn_table_entry->body_node, 4);
|
||||
fprintf(stderr, "\n{ // (IR)\n");
|
||||
ir_print(stderr, &fn_table_entry->ir_executable, 4);
|
||||
fprintf(stderr, "}\n");
|
||||
|
@ -170,6 +170,8 @@ static const char *node_type_str(NodeType node_type) {
|
||||
return "TypeDecl";
|
||||
case NodeTypeErrorValueDecl:
|
||||
return "ErrorValueDecl";
|
||||
case NodeTypeTestDecl:
|
||||
return "TestDecl";
|
||||
case NodeTypeNumberLiteral:
|
||||
return "NumberLiteral";
|
||||
case NodeTypeStringLiteral:
|
||||
@ -915,6 +917,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
|
||||
case NodeTypeFnDecl:
|
||||
case NodeTypeParamDecl:
|
||||
case NodeTypeErrorValueDecl:
|
||||
case NodeTypeTestDecl:
|
||||
case NodeTypeStructField:
|
||||
case NodeTypeUse:
|
||||
zig_panic("TODO more ast rendering");
|
||||
|
@ -138,10 +138,6 @@ void codegen_set_verbose(CodeGen *g, bool verbose) {
|
||||
g->verbose = verbose;
|
||||
}
|
||||
|
||||
void codegen_set_check_unused(CodeGen *g, bool check_unused) {
|
||||
g->check_unused = check_unused;
|
||||
}
|
||||
|
||||
void codegen_set_each_lib_rpath(CodeGen *g, bool each_lib_rpath) {
|
||||
g->each_lib_rpath = each_lib_rpath;
|
||||
}
|
||||
@ -323,7 +319,7 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
|
||||
return get_di_scope(g, scope->parent);
|
||||
unsigned line_number = fn_table_entry->proto_node->line + 1;
|
||||
unsigned scope_line = line_number;
|
||||
bool is_definition = fn_table_entry->fn_def_node != nullptr;
|
||||
bool is_definition = fn_table_entry->body_node != nullptr;
|
||||
unsigned flags = 0;
|
||||
bool is_optimized = g->is_release_build;
|
||||
ZigLLVMDISubprogram *subprogram = ZigLLVMCreateFunction(g->dbuilder,
|
||||
@ -2492,7 +2488,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
|
||||
case IrInstructionIdToPtrType:
|
||||
case IrInstructionIdPtrTypeChild:
|
||||
case IrInstructionIdFieldPtr:
|
||||
case IrInstructionIdSetFnTest:
|
||||
case IrInstructionIdSetFnVisible:
|
||||
case IrInstructionIdSetDebugSafety:
|
||||
case IrInstructionIdArrayType:
|
||||
@ -4054,7 +4049,6 @@ static void define_builtin_fns(CodeGen *g) {
|
||||
create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX);
|
||||
create_builtin_fn(g, BuiltinFnIdIntType, "intType", 2);
|
||||
create_builtin_fn(g, BuiltinFnIdUnreachable, "unreachable", 0);
|
||||
create_builtin_fn(g, BuiltinFnIdSetFnTest, "setFnTest", 1);
|
||||
create_builtin_fn(g, BuiltinFnIdSetFnVisible, "setFnVisible", 2);
|
||||
create_builtin_fn(g, BuiltinFnIdSetDebugSafety, "setDebugSafety", 2);
|
||||
create_builtin_fn(g, BuiltinFnIdAlloca, "alloca", 2);
|
||||
|
@ -19,7 +19,6 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target);
|
||||
void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len);
|
||||
void codegen_set_is_release(CodeGen *codegen, bool is_release);
|
||||
void codegen_set_is_test(CodeGen *codegen, bool is_test);
|
||||
void codegen_set_check_unused(CodeGen *codegen, bool check_unused);
|
||||
void codegen_set_each_lib_rpath(CodeGen *codegen, bool each_lib_rpath);
|
||||
|
||||
void codegen_set_is_static(CodeGen *codegen, bool is_static);
|
||||
|
65
src/ir.cpp
65
src/ir.cpp
@ -282,10 +282,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrTypeChild *)
|
||||
return IrInstructionIdPtrTypeChild;
|
||||
}
|
||||
|
||||
static constexpr IrInstructionId ir_instruction_id(IrInstructionSetFnTest *) {
|
||||
return IrInstructionIdSetFnTest;
|
||||
}
|
||||
|
||||
static constexpr IrInstructionId ir_instruction_id(IrInstructionSetFnVisible *) {
|
||||
return IrInstructionIdSetFnVisible;
|
||||
}
|
||||
@ -1147,17 +1143,6 @@ static IrInstruction *ir_build_ptr_type_child(IrBuilder *irb, Scope *scope, AstN
|
||||
return &instruction->base;
|
||||
}
|
||||
|
||||
static IrInstruction *ir_build_set_fn_test(IrBuilder *irb, Scope *scope, AstNode *source_node,
|
||||
IrInstruction *fn_value)
|
||||
{
|
||||
IrInstructionSetFnTest *instruction = ir_build_instruction<IrInstructionSetFnTest>(irb, scope, source_node);
|
||||
instruction->fn_value = fn_value;
|
||||
|
||||
ir_ref_instruction(fn_value, irb->current_basic_block);
|
||||
|
||||
return &instruction->base;
|
||||
}
|
||||
|
||||
static IrInstruction *ir_build_set_fn_visible(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *fn_value,
|
||||
IrInstruction *is_visible)
|
||||
{
|
||||
@ -2287,13 +2272,6 @@ static IrInstruction *ir_instruction_ptrtypechild_get_dep(IrInstructionPtrTypeCh
|
||||
}
|
||||
}
|
||||
|
||||
static IrInstruction *ir_instruction_setfntest_get_dep(IrInstructionSetFnTest *instruction, size_t index) {
|
||||
switch (index) {
|
||||
case 0: return instruction->fn_value;
|
||||
default: return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static IrInstruction *ir_instruction_setfnvisible_get_dep(IrInstructionSetFnVisible *instruction, size_t index) {
|
||||
switch (index) {
|
||||
case 0: return instruction->fn_value;
|
||||
@ -2807,8 +2785,6 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
|
||||
return ir_instruction_toptrtype_get_dep((IrInstructionToPtrType *) instruction, index);
|
||||
case IrInstructionIdPtrTypeChild:
|
||||
return ir_instruction_ptrtypechild_get_dep((IrInstructionPtrTypeChild *) instruction, index);
|
||||
case IrInstructionIdSetFnTest:
|
||||
return ir_instruction_setfntest_get_dep((IrInstructionSetFnTest *) instruction, index);
|
||||
case IrInstructionIdSetFnVisible:
|
||||
return ir_instruction_setfnvisible_get_dep((IrInstructionSetFnVisible *) instruction, index);
|
||||
case IrInstructionIdSetDebugSafety:
|
||||
@ -3810,15 +3786,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
|
||||
return arg;
|
||||
return ir_build_typeof(irb, scope, node, arg);
|
||||
}
|
||||
case BuiltinFnIdSetFnTest:
|
||||
{
|
||||
AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
|
||||
IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
|
||||
if (arg0_value == irb->codegen->invalid_instruction)
|
||||
return arg0_value;
|
||||
|
||||
return ir_build_set_fn_test(irb, scope, node, arg0_value);
|
||||
}
|
||||
case BuiltinFnIdSetFnVisible:
|
||||
{
|
||||
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
|
||||
zig_panic("TODO IR gen NodeTypeErrorValueDecl");
|
||||
case NodeTypeTypeDecl:
|
||||
zig_panic("TODO IR gen NodeTypeTypeDecl");
|
||||
case NodeTypeTestDecl:
|
||||
zig_panic("TODO IR gen NodeTypeTestDecl");
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
@ -5633,10 +5602,7 @@ bool ir_gen_fn(CodeGen *codegen, FnTableEntry *fn_entry) {
|
||||
assert(fn_entry);
|
||||
|
||||
IrExecutable *ir_executable = &fn_entry->ir_executable;
|
||||
AstNode *fn_def_node = fn_entry->fn_def_node;
|
||||
assert(fn_def_node->type == NodeTypeFnDef);
|
||||
|
||||
AstNode *body_node = fn_def_node->data.fn_def.body;
|
||||
AstNode *body_node = fn_entry->body_node;
|
||||
|
||||
assert(fn_entry->child_scope);
|
||||
|
||||
@ -8180,7 +8146,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
|
||||
result = entry->value;
|
||||
} else {
|
||||
// Analyze the fn body block like any other constant expression.
|
||||
AstNode *body_node = fn_entry->fn_def_node->data.fn_def.body;
|
||||
AstNode *body_node = fn_entry->body_node;
|
||||
result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type,
|
||||
ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry,
|
||||
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
|
||||
FnTableEntry *impl_fn = create_fn(fn_proto_node);
|
||||
impl_fn->param_source_nodes = allocate<AstNode *>(new_fn_arg_count);
|
||||
buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name);
|
||||
impl_fn->fndef_scope = create_fndef_scope(impl_fn->fn_def_node, parent_scope, impl_fn);
|
||||
impl_fn->fndef_scope = create_fndef_scope(impl_fn->body_node, parent_scope, impl_fn);
|
||||
impl_fn->child_scope = &impl_fn->fndef_scope->base;
|
||||
FnTypeId inst_fn_type_id = {0};
|
||||
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,
|
||||
return ira->codegen->builtin_types.entry_type;
|
||||
}
|
||||
|
||||
static TypeTableEntry *ir_analyze_instruction_set_fn_test(IrAnalyze *ira,
|
||||
IrInstructionSetFnTest *set_fn_test_instruction)
|
||||
{
|
||||
IrInstruction *fn_value = set_fn_test_instruction->fn_value->other;
|
||||
|
||||
FnTableEntry *fn_entry = ir_resolve_fn(ira, fn_value);
|
||||
if (!fn_entry)
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
|
||||
if (!fn_entry->is_test) {
|
||||
fn_entry->is_test = true;
|
||||
ira->codegen->test_fn_count += 1;
|
||||
}
|
||||
|
||||
ir_build_const_from(ira, &set_fn_test_instruction->base);
|
||||
return ira->codegen->builtin_types.entry_void;
|
||||
}
|
||||
|
||||
static TypeTableEntry *ir_analyze_instruction_set_fn_visible(IrAnalyze *ira,
|
||||
IrInstructionSetFnVisible *set_fn_visible_instruction)
|
||||
{
|
||||
@ -12253,8 +12201,6 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
|
||||
return ir_analyze_instruction_to_ptr_type(ira, (IrInstructionToPtrType *)instruction);
|
||||
case IrInstructionIdPtrTypeChild:
|
||||
return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction);
|
||||
case IrInstructionIdSetFnTest:
|
||||
return ir_analyze_instruction_set_fn_test(ira, (IrInstructionSetFnTest *)instruction);
|
||||
case IrInstructionIdSetFnVisible:
|
||||
return ir_analyze_instruction_set_fn_visible(ira, (IrInstructionSetFnVisible *)instruction);
|
||||
case IrInstructionIdSetGlobalAlign:
|
||||
@ -12469,7 +12415,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
|
||||
case IrInstructionIdCall:
|
||||
case IrInstructionIdReturn:
|
||||
case IrInstructionIdUnreachable:
|
||||
case IrInstructionIdSetFnTest:
|
||||
case IrInstructionIdSetFnVisible:
|
||||
case IrInstructionIdSetDebugSafety:
|
||||
case IrInstructionIdImport:
|
||||
|
@ -339,12 +339,6 @@ static void ir_print_enum_field_ptr(IrPrint *irp, IrInstructionEnumFieldPtr *ins
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_set_fn_test(IrPrint *irp, IrInstructionSetFnTest *instruction) {
|
||||
fprintf(irp->f, "@setFnTest(");
|
||||
ir_print_other_instruction(irp, instruction->fn_value);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_set_fn_visible(IrPrint *irp, IrInstructionSetFnVisible *instruction) {
|
||||
fprintf(irp->f, "@setFnVisible(");
|
||||
ir_print_other_instruction(irp, instruction->fn_value);
|
||||
@ -932,9 +926,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
|
||||
case IrInstructionIdEnumFieldPtr:
|
||||
ir_print_enum_field_ptr(irp, (IrInstructionEnumFieldPtr *)instruction);
|
||||
break;
|
||||
case IrInstructionIdSetFnTest:
|
||||
ir_print_set_fn_test(irp, (IrInstructionSetFnTest *)instruction);
|
||||
break;
|
||||
case IrInstructionIdSetFnVisible:
|
||||
ir_print_set_fn_visible(irp, (IrInstructionSetFnVisible *)instruction);
|
||||
break;
|
||||
|
@ -56,7 +56,6 @@ static int usage(const char *arg0) {
|
||||
" -mmacosx-version-min [ver] (darwin only) set Mac OS X deployment target\n"
|
||||
" -mios-version-min [ver] (darwin only) set iOS deployment target\n"
|
||||
" -framework [name] (darwin only) link against framework\n"
|
||||
" --check-unused perform semantic analysis on unused declarations\n"
|
||||
" --linker-script [path] use a custom linker script\n"
|
||||
" -rpath [path] add directory to the runtime library search path\n"
|
||||
" --each-lib-rpath add rpath for each used dynamic library\n"
|
||||
@ -141,7 +140,6 @@ int main(int argc, char **argv) {
|
||||
bool rdynamic = false;
|
||||
const char *mmacosx_version_min = nullptr;
|
||||
const char *mios_version_min = nullptr;
|
||||
bool check_unused = false;
|
||||
const char *linker_script = nullptr;
|
||||
ZigList<const char *> rpath_list = {0};
|
||||
bool each_lib_rpath = false;
|
||||
@ -166,8 +164,6 @@ int main(int argc, char **argv) {
|
||||
municode = true;
|
||||
} else if (strcmp(arg, "-rdynamic") == 0) {
|
||||
rdynamic = true;
|
||||
} else if (strcmp(arg, "--check-unused") == 0) {
|
||||
check_unused = true;
|
||||
} else if (strcmp(arg, "--each-lib-rpath") == 0) {
|
||||
each_lib_rpath = true;
|
||||
} else if (arg[1] == 'L' && arg[2] != 0) {
|
||||
@ -354,7 +350,6 @@ int main(int argc, char **argv) {
|
||||
codegen_set_is_release(g, is_release_build);
|
||||
codegen_set_is_test(g, cmd == CmdTest);
|
||||
codegen_set_linker_script(g, linker_script);
|
||||
codegen_set_check_unused(g, check_unused);
|
||||
if (each_lib_rpath)
|
||||
codegen_set_each_lib_rpath(g, each_lib_rpath);
|
||||
|
||||
|
@ -2417,6 +2417,27 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, size_t *token_index
|
||||
return node;
|
||||
}
|
||||
|
||||
/*
|
||||
TestDecl = "test" String Block
|
||||
*/
|
||||
static AstNode *ast_parse_test_decl_node(ParseContext *pc, size_t *token_index, VisibMod visib_mod) {
|
||||
Token *first_token = &pc->tokens->at(*token_index);
|
||||
|
||||
if (first_token->id != TokenIdKeywordTest) {
|
||||
return nullptr;
|
||||
}
|
||||
*token_index += 1;
|
||||
|
||||
Token *name_tok = ast_eat_token(pc, token_index, TokenIdStringLiteral);
|
||||
|
||||
AstNode *node = ast_create_node(pc, NodeTypeTestDecl, first_token);
|
||||
node->data.test_decl.visib_mod = visib_mod;
|
||||
node->data.test_decl.name = token_buf(name_tok);
|
||||
node->data.test_decl.body = ast_parse_block(pc, token_index, true);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/*
|
||||
TypeDecl = "type" "Symbol" "=" TypeExpr ";"
|
||||
*/
|
||||
@ -2443,7 +2464,7 @@ static AstNode *ast_parse_type_decl(ParseContext *pc, size_t *token_index, Visib
|
||||
}
|
||||
|
||||
/*
|
||||
TopLevelItem = ErrorValueDecl | Block | TopLevelDecl
|
||||
TopLevelItem = ErrorValueDecl | Block | TopLevelDecl | TestDecl
|
||||
TopLevelDecl = option(VisibleMod) (FnDef | ExternDecl | GlobalVarDecl | TypeDecl | UseDecl)
|
||||
*/
|
||||
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
|
||||
continue;
|
||||
}
|
||||
|
||||
AstNode *test_decl_node = ast_parse_test_decl_node(pc, token_index, visib_mod);
|
||||
if (test_decl_node) {
|
||||
top_level_decls->append(test_decl_node);
|
||||
continue;
|
||||
}
|
||||
|
||||
AstNode *type_decl_node = ast_parse_type_decl(pc, token_index, visib_mod);
|
||||
if (type_decl_node) {
|
||||
top_level_decls->append(type_decl_node);
|
||||
@ -2585,6 +2612,9 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
|
||||
case NodeTypeErrorValueDecl:
|
||||
// none
|
||||
break;
|
||||
case NodeTypeTestDecl:
|
||||
visit_field(&node->data.test_decl.body, visit, context);
|
||||
break;
|
||||
case NodeTypeBinOpExpr:
|
||||
visit_field(&node->data.bin_op_expr.op1, visit, context);
|
||||
visit_field(&node->data.bin_op_expr.op2, visit, context);
|
||||
|
@ -133,6 +133,7 @@ static const struct ZigKeyword zig_keywords[] = {
|
||||
{"return", TokenIdKeywordReturn},
|
||||
{"struct", TokenIdKeywordStruct},
|
||||
{"switch", TokenIdKeywordSwitch},
|
||||
{"test", TokenIdKeywordTest},
|
||||
{"this", TokenIdKeywordThis},
|
||||
{"true", TokenIdKeywordTrue},
|
||||
{"try", TokenIdKeywordTry},
|
||||
@ -1508,6 +1509,7 @@ const char * token_name(TokenId id) {
|
||||
case TokenIdKeywordReturn: return "return";
|
||||
case TokenIdKeywordStruct: return "struct";
|
||||
case TokenIdKeywordSwitch: return "switch";
|
||||
case TokenIdKeywordTest: return "test";
|
||||
case TokenIdKeywordThis: return "this";
|
||||
case TokenIdKeywordTrue: return "true";
|
||||
case TokenIdKeywordTry: return "try";
|
||||
|
@ -74,6 +74,7 @@ enum TokenId {
|
||||
TokenIdKeywordReturn,
|
||||
TokenIdKeywordStruct,
|
||||
TokenIdKeywordSwitch,
|
||||
TokenIdKeywordTest,
|
||||
TokenIdKeywordThis,
|
||||
TokenIdKeywordTrue,
|
||||
TokenIdKeywordTry,
|
||||
|
@ -322,9 +322,7 @@ export fn __udivsi3(n: su_int, d: su_int) -> su_int {
|
||||
return q;
|
||||
}
|
||||
|
||||
fn test_umoddi3() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "test_umoddi3" {
|
||||
test_one_umoddi3(0, 1, 0);
|
||||
test_one_umoddi3(2, 1, 0);
|
||||
test_one_umoddi3(0x8000000000000000, 1, 0x0);
|
||||
@ -337,9 +335,7 @@ fn test_one_umoddi3(a: du_int, b: du_int, expected_r: du_int) {
|
||||
assert(r == expected_r);
|
||||
}
|
||||
|
||||
fn test_udivmoddi4() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "test_udivmoddi4" {
|
||||
const cases = [][4]du_int {
|
||||
[]du_int{0x0000000000000000, 0x0000000000000001, 0x0000000000000000, 0x0000000000000000},
|
||||
[]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_
|
||||
assert(r == expected_r);
|
||||
}
|
||||
|
||||
fn test_udivsi3() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "test_udivsi3" {
|
||||
const cases = [][3]su_int {
|
||||
[]su_int{0x00000000, 0x00000001, 0x00000000},
|
||||
[]su_int{0x00000000, 0x00000002, 0x00000000},
|
||||
|
@ -140,9 +140,7 @@ pub const Buffer0 = struct {
|
||||
}
|
||||
};
|
||||
|
||||
fn testSimpleBuffer0() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "simple Buffer0" {
|
||||
var buf = %%Buffer0.initEmpty(&debug.global_allocator);
|
||||
assert(buf.len() == 0);
|
||||
%%buf.appendCStr(c"hello");
|
||||
@ -162,9 +160,7 @@ fn testSimpleBuffer0() {
|
||||
assert(buf.startsWithOther(&buf2));
|
||||
}
|
||||
|
||||
fn testCStrFns() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "cstr fns" {
|
||||
comptime testCStrFnsImpl();
|
||||
testCStrFnsImpl();
|
||||
}
|
||||
|
12
std/fmt.zig
12
std/fmt.zig
@ -291,9 +291,7 @@ fn digitToChar(digit: u8, uppercase: bool) -> u8 {
|
||||
};
|
||||
}
|
||||
|
||||
fn testBufPrintInt() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "testBufPrintInt" {
|
||||
var buffer: [max_int_digits]u8 = undefined;
|
||||
const buf = buffer[0...];
|
||||
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
|
||||
return buf[0...formatIntBuf(buf, value, base, uppercase, width)];
|
||||
}
|
||||
|
||||
fn testParseU64DigitTooBig() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "testParseU64DigitTooBig" {
|
||||
parseUnsigned(u64, "123a", 10) %% |err| {
|
||||
if (err == error.InvalidChar) return;
|
||||
@unreachable();
|
||||
@ -325,9 +321,7 @@ fn testParseU64DigitTooBig() {
|
||||
@unreachable();
|
||||
}
|
||||
|
||||
fn testParseUnsignedComptime() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "testParseUnsignedComptime" {
|
||||
comptime {
|
||||
assert(%%parseUnsigned(usize, "2", 10) == 2);
|
||||
}
|
||||
|
@ -219,9 +219,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
|
||||
}
|
||||
}
|
||||
|
||||
fn basicHashMapTest() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "basicHashMapTest" {
|
||||
var map: HashMap(i32, i32, hash_i32, eql_i32) = undefined;
|
||||
map.init(&debug.global_allocator);
|
||||
defer map.deinit();
|
||||
|
@ -64,9 +64,7 @@ pub fn List(comptime T: type) -> type{
|
||||
}
|
||||
}
|
||||
|
||||
fn basicListTest() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "basicListTest" {
|
||||
var list = List(i32).init(&debug.global_allocator);
|
||||
defer list.deinit();
|
||||
|
||||
|
@ -68,9 +68,7 @@ fn getReturnTypeForAbs(comptime T: type) -> type {
|
||||
}
|
||||
}
|
||||
|
||||
fn testMath() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "testMath" {
|
||||
testMathImpl();
|
||||
comptime testMathImpl();
|
||||
}
|
||||
|
12
std/mem.zig
12
std/mem.zig
@ -117,17 +117,13 @@ pub fn writeInt(buf: []u8, value: var, big_endian: bool) {
|
||||
assert(bits == 0);
|
||||
}
|
||||
|
||||
fn testStringEquality() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "testStringEquality" {
|
||||
assert(eql(u8, "abcd", "abcd"));
|
||||
assert(!eql(u8, "abcdef", "abZdef"));
|
||||
assert(!eql(u8, "abcdefg", "abcdef"));
|
||||
}
|
||||
|
||||
fn testReadInt() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "testReadInt" {
|
||||
testReadIntImpl();
|
||||
comptime testReadIntImpl();
|
||||
}
|
||||
@ -149,9 +145,7 @@ fn testReadIntImpl() {
|
||||
}
|
||||
}
|
||||
|
||||
fn testWriteInt() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "testWriteInt" {
|
||||
testWriteIntImpl();
|
||||
comptime testWriteIntImpl();
|
||||
}
|
||||
|
12
std/rand.zig
12
std/rand.zig
@ -158,9 +158,7 @@ fn MersenneTwister(
|
||||
}
|
||||
}
|
||||
|
||||
fn testFloat32() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "testFloat32" {
|
||||
var r: Rand = undefined;
|
||||
r.init(42);
|
||||
|
||||
@ -171,9 +169,7 @@ fn testFloat32() {
|
||||
}}
|
||||
}
|
||||
|
||||
fn testMT19937_64() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "testMT19937_64" {
|
||||
var rng: MT19937_64 = undefined;
|
||||
rng.init(rand_test.mt64_seed);
|
||||
for (rand_test.mt64_data) |value| {
|
||||
@ -181,9 +177,7 @@ fn testMT19937_64() {
|
||||
}
|
||||
}
|
||||
|
||||
fn testMT19937_32() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "testMT19937_32" {
|
||||
var rng: MT19937_32 = undefined;
|
||||
rng.init(rand_test.mt32_seed);
|
||||
for (rand_test.mt32_data) |value| {
|
||||
|
@ -58,9 +58,7 @@ fn reverse(was: Cmp) -> Cmp {
|
||||
// ---------------------------------------
|
||||
// tests
|
||||
|
||||
fn testSort() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "testSort" {
|
||||
const u8cases = [][]const []const u8 {
|
||||
[][]const u8{"", ""},
|
||||
[][]const u8{"a", "a"},
|
||||
@ -96,9 +94,7 @@ fn testSort() {
|
||||
}
|
||||
}
|
||||
|
||||
fn testSortDesc() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "testSortDesc" {
|
||||
const rev_cases = [][]const []const i32 {
|
||||
[][]const i32{[]i32{}, []i32{}},
|
||||
[][]const i32{[]i32{1}, []i32{1}},
|
||||
|
@ -1,9 +1,7 @@
|
||||
const assert = @import("std").debug.assert;
|
||||
const mem = @import("std").mem;
|
||||
|
||||
fn arrays() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "arrays" {
|
||||
var array : [5]u32 = undefined;
|
||||
|
||||
var i : u32 = 0;
|
||||
@ -27,9 +25,7 @@ fn getArrayLen(a: []const u32) -> usize {
|
||||
a.len
|
||||
}
|
||||
|
||||
fn voidArrays() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "voidArrays" {
|
||||
var array: [4]void = undefined;
|
||||
array[0] = void{};
|
||||
array[1] = array[2];
|
||||
@ -37,18 +33,14 @@ fn voidArrays() {
|
||||
assert(array.len == 4);
|
||||
}
|
||||
|
||||
fn arrayLiteral() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "arrayLiteral" {
|
||||
const hex_mult = []u16{4096, 256, 16, 1};
|
||||
|
||||
assert(hex_mult.len == 4);
|
||||
assert(hex_mult[1] == 256);
|
||||
}
|
||||
|
||||
fn arrayDotLenConstExpr() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "arrayDotLenConstExpr" {
|
||||
assert(comptime {some_array.len == 4});
|
||||
}
|
||||
|
||||
@ -58,9 +50,7 @@ const ArrayDotLenConstExpr = struct {
|
||||
const some_array = []u8 {0, 1, 2, 3};
|
||||
|
||||
|
||||
fn nestedArrays() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "nestedArrays" {
|
||||
const array_of_strings = [][]const u8 {"hello", "this", "is", "my", "thing"};
|
||||
for (array_of_strings) |s, i| {
|
||||
if (i == 0) assert(mem.eql(u8, s, "hello"));
|
||||
@ -79,9 +69,7 @@ const Sub = struct {
|
||||
const Str = struct {
|
||||
a: []Sub,
|
||||
};
|
||||
fn setGlobalVarArrayViaSliceEmbeddedInStruct() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "setGlobalVarArrayViaSliceEmbeddedInStruct" {
|
||||
var s = Str { .a = s_array[0...]};
|
||||
|
||||
s.a[0].b = 1;
|
||||
|
@ -1,16 +1,12 @@
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
fn cmpxchg() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "cmpxchg" {
|
||||
var x: i32 = 1234;
|
||||
while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) {}
|
||||
assert(x == 5678);
|
||||
}
|
||||
|
||||
fn fence() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "fence" {
|
||||
var x: i32 = 1234;
|
||||
@fence(AtomicOrder.SeqCst);
|
||||
x = 5678;
|
||||
|
@ -1,15 +1,11 @@
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
fn boolLiterals() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "boolLiterals" {
|
||||
assert(true);
|
||||
assert(!false);
|
||||
}
|
||||
|
||||
fn castBoolToInt() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "castBoolToInt" {
|
||||
const t = true;
|
||||
const f = false;
|
||||
assert(i32(t) == i32(1));
|
||||
@ -22,18 +18,14 @@ fn nonConstCastBoolToInt(t: bool, f: bool) {
|
||||
assert(i32(f) == i32(0));
|
||||
}
|
||||
|
||||
fn boolCmp() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "boolCmp" {
|
||||
assert(testBoolCmp(true, false) == false);
|
||||
}
|
||||
fn testBoolCmp(a: bool, b: bool) -> bool {
|
||||
a == b
|
||||
}
|
||||
|
||||
fn shortCircuitAndOr() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "shortCircuitAndOr" {
|
||||
var a = true;
|
||||
a &&= false;
|
||||
assert(!a);
|
||||
@ -49,9 +41,7 @@ const global_f = false;
|
||||
const global_t = true;
|
||||
const not_global_f = !global_f;
|
||||
const not_global_t = !global_t;
|
||||
fn compileTimeBoolnot() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "compileTimeBoolnot" {
|
||||
assert(not_global_f);
|
||||
assert(!not_global_t);
|
||||
}
|
||||
|
@ -1,24 +1,18 @@
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
fn intToPtrCast() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "intToPtrCast" {
|
||||
const x = isize(13);
|
||||
const y = (&u8)(x);
|
||||
const z = usize(y);
|
||||
assert(z == 13);
|
||||
}
|
||||
|
||||
fn numLitIntToPtrCast() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "numLitIntToPtrCast" {
|
||||
const vga_mem = (&u16)(0xB8000);
|
||||
assert(usize(vga_mem) == 0xB8000);
|
||||
}
|
||||
|
||||
fn pointerReinterpretConstFloatToInt() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "pointerReinterpretConstFloatToInt" {
|
||||
const float: f64 = 5.99999999999994648725e-01;
|
||||
const float_ptr = &float;
|
||||
const int_ptr = (&i32)(float_ptr);
|
||||
|
@ -2,9 +2,7 @@ const assert = @import("std").debug.assert;
|
||||
|
||||
var argv: &const &const u8 = undefined;
|
||||
|
||||
fn constSliceChild() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "constSliceChild" {
|
||||
const strs = ([]&const u8) {
|
||||
c"one",
|
||||
c"two",
|
||||
|
@ -21,9 +21,7 @@ fn runSomeMaybeDefers(x: bool) -> ?bool {
|
||||
return if (x) x else null;
|
||||
}
|
||||
|
||||
fn mixingNormalAndErrorDefers() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "mixingNormalAndErrorDefers" {
|
||||
assert(%%runSomeErrorDefers(true));
|
||||
assert(result[0] == 'c');
|
||||
assert(result[1] == 'a');
|
||||
@ -38,9 +36,7 @@ fn mixingNormalAndErrorDefers() {
|
||||
assert(result[2] == 'a');
|
||||
}
|
||||
|
||||
fn mixingNormalAndMaybeDefers() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "mixingNormalAndMaybeDefers" {
|
||||
assert(??runSomeMaybeDefers(true));
|
||||
assert(result[0] == 'c');
|
||||
assert(result[1] == 'a');
|
||||
|
@ -1,8 +1,6 @@
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
fn enumType() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "enumType" {
|
||||
const foo1 = Foo.One {13};
|
||||
const foo2 = Foo.Two { Point { .x = 1234, .y = 5678, }};
|
||||
const bar = Bar.B;
|
||||
@ -15,9 +13,7 @@ fn enumType() {
|
||||
assert(@sizeOf(Bar) == 1);
|
||||
}
|
||||
|
||||
fn enumAsReturnValue () {
|
||||
@setFnTest(this);
|
||||
|
||||
test "enumAsReturnValue" {
|
||||
switch (returnAnInt(13)) {
|
||||
Foo.One => |value| assert(value == 13),
|
||||
else => @unreachable(),
|
||||
@ -45,9 +41,7 @@ fn returnAnInt(x: i32) -> Foo {
|
||||
}
|
||||
|
||||
|
||||
fn constantEnumWithPayload() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "constantEnumWithPayload" {
|
||||
var empty = AnEnumWithPayload.Empty;
|
||||
var full = AnEnumWithPayload.Full {13};
|
||||
shouldBeEmpty(empty);
|
||||
@ -83,9 +77,7 @@ const Number = enum {
|
||||
Four,
|
||||
};
|
||||
|
||||
fn enumToInt() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "enumToInt" {
|
||||
shouldEqual(Number.Zero, 0);
|
||||
shouldEqual(Number.One, 1);
|
||||
shouldEqual(Number.Two, 2);
|
||||
@ -98,9 +90,7 @@ fn shouldEqual(n: Number, expected: usize) {
|
||||
}
|
||||
|
||||
|
||||
fn intToEnum() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "intToEnum" {
|
||||
testIntToEnumEval(3);
|
||||
}
|
||||
fn testIntToEnumEval(x: i32) {
|
||||
|
@ -14,9 +14,7 @@ const ET = enum {
|
||||
}
|
||||
};
|
||||
|
||||
fn enumWithMembers() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "enumWithMembers" {
|
||||
const a = ET.SINT { -42 };
|
||||
const b = ET.UINT { 42 };
|
||||
var buf: [20]u8 = undefined;
|
||||
|
@ -15,9 +15,7 @@ pub fn baz() -> %i32 {
|
||||
return y + 1;
|
||||
}
|
||||
|
||||
fn errorWrapping() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "errorWrapping" {
|
||||
assert(%%baz() == 15);
|
||||
}
|
||||
|
||||
@ -26,8 +24,7 @@ fn gimmeItBroke() -> []const u8 {
|
||||
@errorName(error.ItBroke)
|
||||
}
|
||||
|
||||
fn errorName() {
|
||||
@setFnTest(this);
|
||||
test "errorName" {
|
||||
assert(mem.eql(u8, @errorName(error.AnError), "AnError"));
|
||||
assert(mem.eql(u8, @errorName(error.ALongerErrorName), "ALongerErrorName"));
|
||||
}
|
||||
@ -35,9 +32,7 @@ error AnError;
|
||||
error ALongerErrorName;
|
||||
|
||||
|
||||
fn errorValues() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "errorValues" {
|
||||
const a = i32(error.err1);
|
||||
const b = i32(error.err2);
|
||||
assert(a != b);
|
||||
@ -46,9 +41,7 @@ error err1;
|
||||
error err2;
|
||||
|
||||
|
||||
fn redefinitionOfErrorValuesAllowed() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "redefinitionOfErrorValuesAllowed" {
|
||||
shouldBeNotEqual(error.AnError, error.SecondError);
|
||||
}
|
||||
error AnError;
|
||||
@ -59,9 +52,7 @@ fn shouldBeNotEqual(a: error, b: error) {
|
||||
}
|
||||
|
||||
|
||||
fn errBinaryOperator() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "errBinaryOperator" {
|
||||
const a = errBinaryOperatorG(true) %% 3;
|
||||
const b = errBinaryOperatorG(false) %% 3;
|
||||
assert(a == 3);
|
||||
@ -77,18 +68,14 @@ fn errBinaryOperatorG(x: bool) -> %isize {
|
||||
}
|
||||
|
||||
|
||||
fn unwrapSimpleValueFromError() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "unwrapSimpleValueFromError" {
|
||||
const i = %%unwrapSimpleValueFromErrorDo();
|
||||
assert(i == 13);
|
||||
}
|
||||
fn unwrapSimpleValueFromErrorDo() -> %isize { 13 }
|
||||
|
||||
|
||||
fn errReturnInAssignment() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "errReturnInAssignment" {
|
||||
%%doErrReturnInAssignment();
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
fn compileTimeRecursion() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "compileTimeRecursion" {
|
||||
assert(some_data.len == 21);
|
||||
}
|
||||
var some_data: [usize(fibonacci(7))]u8 = undefined;
|
||||
@ -17,14 +15,11 @@ fn unwrapAndAddOne(blah: ?i32) -> i32 {
|
||||
return ??blah + 1;
|
||||
}
|
||||
const should_be_1235 = unwrapAndAddOne(1234);
|
||||
fn testStaticAddOne() {
|
||||
@setFnTest(this);
|
||||
test "testStaticAddOne" {
|
||||
assert(should_be_1235 == 1235);
|
||||
}
|
||||
|
||||
fn inlinedLoop() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "inlinedLoop" {
|
||||
comptime var i = 0;
|
||||
comptime var sum = 0;
|
||||
inline while (i <= 5; i += 1)
|
||||
@ -38,25 +33,20 @@ fn gimme1or2(comptime a: bool) -> i32 {
|
||||
comptime var z: i32 = if (a) x else y;
|
||||
return z;
|
||||
}
|
||||
fn inlineVariableGetsResultOfConstIf() {
|
||||
@setFnTest(this);
|
||||
test "inlineVariableGetsResultOfConstIf" {
|
||||
assert(gimme1or2(true) == 1);
|
||||
assert(gimme1or2(false) == 2);
|
||||
}
|
||||
|
||||
|
||||
fn staticFunctionEvaluation() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "staticFunctionEvaluation" {
|
||||
assert(statically_added_number == 3);
|
||||
}
|
||||
const statically_added_number = staticAdd(1, 2);
|
||||
fn staticAdd(a: i32, b: i32) -> i32 { a + b }
|
||||
|
||||
|
||||
fn constExprEvalOnSingleExprBlocks() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "constExprEvalOnSingleExprBlocks" {
|
||||
assert(constExprEvalOnSingleExprBlocksFn(1, true) == 3);
|
||||
}
|
||||
|
||||
@ -75,9 +65,7 @@ fn constExprEvalOnSingleExprBlocksFn(x: i32, b: bool) -> i32 {
|
||||
|
||||
|
||||
|
||||
fn staticallyInitalizedList() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "staticallyInitalizedList" {
|
||||
assert(static_point_list[0].x == 1);
|
||||
assert(static_point_list[0].y == 2);
|
||||
assert(static_point_list[1].x == 3);
|
||||
@ -96,9 +84,7 @@ fn makePoint(x: i32, y: i32) -> Point {
|
||||
}
|
||||
|
||||
|
||||
fn staticEvalListInit() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "staticEvalListInit" {
|
||||
assert(static_vec3.data[2] == 1.0);
|
||||
assert(vec3(0.0, 0.0, 3.0).data[2] == 3.0);
|
||||
}
|
||||
@ -113,18 +99,14 @@ pub fn vec3(x: f32, y: f32, z: f32) -> Vec3 {
|
||||
}
|
||||
|
||||
|
||||
fn constantExpressions() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "constantExpressions" {
|
||||
var array : [array_size]u8 = undefined;
|
||||
assert(@sizeOf(@typeOf(array)) == 20);
|
||||
}
|
||||
const array_size : u8 = 20;
|
||||
|
||||
|
||||
fn constantStructWithNegation() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "constantStructWithNegation" {
|
||||
assert(vertices[0].x == -0.6);
|
||||
}
|
||||
const Vertex = struct {
|
||||
@ -141,9 +123,7 @@ const vertices = []Vertex {
|
||||
};
|
||||
|
||||
|
||||
fn staticallyInitalizedStruct() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "staticallyInitalizedStruct" {
|
||||
st_init_str_foo.x += 1;
|
||||
assert(st_init_str_foo.x == 14);
|
||||
}
|
||||
@ -154,18 +134,14 @@ const StInitStrFoo = struct {
|
||||
var st_init_str_foo = StInitStrFoo { .x = 13, .y = true, };
|
||||
|
||||
|
||||
fn staticallyInitializedArrayLiteral() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "staticallyInitializedArrayLiteral" {
|
||||
const y : [4]u8 = st_init_arr_lit_x;
|
||||
assert(y[3] == 4);
|
||||
}
|
||||
const st_init_arr_lit_x = []u8{1,2,3,4};
|
||||
|
||||
|
||||
fn constSlice() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "constSlice" {
|
||||
comptime {
|
||||
const a = "1234567890";
|
||||
assert(a.len == 10);
|
||||
@ -175,9 +151,7 @@ fn constSlice() {
|
||||
}
|
||||
}
|
||||
|
||||
fn tryToTrickEvalWithRuntimeIf() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "tryToTrickEvalWithRuntimeIf" {
|
||||
assert(testTryToTrickEvalWithRuntimeIf(true) == 10);
|
||||
}
|
||||
|
||||
@ -203,9 +177,7 @@ fn max(comptime T: type, a: T, b: T) -> T {
|
||||
fn letsTryToCompareBools(a: bool, b: bool) -> bool {
|
||||
max(bool, a, b)
|
||||
}
|
||||
fn inlinedBlockAndRuntimeBlockPhi() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "inlinedBlockAndRuntimeBlockPhi" {
|
||||
assert(letsTryToCompareBools(true, true));
|
||||
assert(letsTryToCompareBools(true, false));
|
||||
assert(letsTryToCompareBools(false, true));
|
||||
@ -244,17 +216,13 @@ fn performFn(comptime prefix_char: u8, start_value: i32) -> i32 {
|
||||
return result;
|
||||
}
|
||||
|
||||
fn comptimeIterateOverFnPtrList() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "comptimeIterateOverFnPtrList" {
|
||||
assert(performFn('t', 1) == 6);
|
||||
assert(performFn('o', 0) == 1);
|
||||
assert(performFn('w', 99) == 99);
|
||||
}
|
||||
|
||||
fn evalSetDebugSafetyAtCompileTime() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "evalSetDebugSafetyAtCompileTime" {
|
||||
const result = comptime fnWithSetDebugSafety();
|
||||
assert(result == 1234);
|
||||
}
|
||||
@ -278,17 +246,13 @@ var simple_struct = SimpleStruct{ .field = 1234, };
|
||||
|
||||
const bound_fn = simple_struct.method;
|
||||
|
||||
fn callMethodOnBoundFnReferringToVarInstance() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "callMethodOnBoundFnReferringToVarInstance" {
|
||||
assert(bound_fn() == 1237);
|
||||
}
|
||||
|
||||
|
||||
|
||||
fn ptrToLocalArrayArgumentAtComptime() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "ptrToLocalArrayArgumentAtComptime" {
|
||||
comptime {
|
||||
var bytes: [10]u8 = undefined;
|
||||
modifySomeBytes(bytes[0...]);
|
||||
|
@ -1,8 +1,6 @@
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
fn params() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "params" {
|
||||
assert(testParamsAdd(22, 11) == 33);
|
||||
}
|
||||
fn testParamsAdd(a: i32, b: i32) -> i32 {
|
||||
@ -10,9 +8,7 @@ fn testParamsAdd(a: i32, b: i32) -> i32 {
|
||||
}
|
||||
|
||||
|
||||
fn localVariables() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "localVariables" {
|
||||
testLocVars(2);
|
||||
}
|
||||
fn testLocVars(b: i32) {
|
||||
@ -21,9 +17,7 @@ fn testLocVars(b: i32) {
|
||||
}
|
||||
|
||||
|
||||
fn voidParameters() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "voidParameters" {
|
||||
voidFun(1, void{}, 2, {});
|
||||
}
|
||||
fn voidFun(a: i32, b: void, c: i32, d: void) {
|
||||
@ -34,9 +28,7 @@ fn voidFun(a: i32, b: void, c: i32, d: void) {
|
||||
}
|
||||
|
||||
|
||||
fn mutableLocalVariables() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "mutableLocalVariables" {
|
||||
var zero : i32 = 0;
|
||||
assert(zero == 0);
|
||||
|
||||
@ -47,9 +39,7 @@ fn mutableLocalVariables() {
|
||||
assert(i == 3);
|
||||
}
|
||||
|
||||
fn separateBlockScopes() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "separateBlockScopes" {
|
||||
{
|
||||
const no_conflict : i32 = 5;
|
||||
assert(no_conflict == 5);
|
||||
@ -62,22 +52,21 @@ fn separateBlockScopes() {
|
||||
assert(c == 10);
|
||||
}
|
||||
|
||||
fn callFnWithEmptyString() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "callFnWithEmptyString" {
|
||||
acceptsString("");
|
||||
}
|
||||
|
||||
fn acceptsString(foo: []u8) { }
|
||||
|
||||
|
||||
fn @"weird function name"() {
|
||||
@setFnTest(this);
|
||||
fn @"weird function name"() -> i32 {
|
||||
return 1234;
|
||||
}
|
||||
test "weird function name" {
|
||||
assert(@"weird function name"() == 1234);
|
||||
}
|
||||
|
||||
fn implicitCastFnUnreachableReturn() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "implicitCastFnUnreachableReturn" {
|
||||
wantsFnWithVoid(fnWithUnreachable);
|
||||
}
|
||||
|
||||
@ -88,9 +77,7 @@ fn fnWithUnreachable() -> unreachable {
|
||||
}
|
||||
|
||||
|
||||
fn functionPointers() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "functionPointers" {
|
||||
const fns = []@typeOf(fn1) { fn1, fn2, fn3, fn4, };
|
||||
for (fns) |f, i| {
|
||||
assert(f() == u32(i) + 5);
|
||||
|
@ -2,9 +2,7 @@ const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
const mem = std.mem;
|
||||
|
||||
fn continueInForLoop() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "continueInForLoop" {
|
||||
const array = []i32 {1, 2, 3, 4, 5};
|
||||
var sum : i32 = 0;
|
||||
for (array) |x| {
|
||||
@ -17,9 +15,7 @@ fn continueInForLoop() {
|
||||
if (sum != 6) @unreachable()
|
||||
}
|
||||
|
||||
fn forLoopWithPointerElemVar() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "forLoopWithPointerElemVar" {
|
||||
const source = "abcdefg";
|
||||
var target: [source.len]u8 = undefined;
|
||||
mem.copy(u8, target[0...], source);
|
||||
@ -32,9 +28,7 @@ fn mangleString(s: []u8) {
|
||||
}
|
||||
}
|
||||
|
||||
fn basicForLoop() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "basicForLoop" {
|
||||
const expected_result = []u8{9, 8, 7, 6, 0, 1, 2, 3, 9, 8, 7, 6, 0, 1, 2, 3 };
|
||||
|
||||
var buffer: [expected_result.len]u8 = undefined;
|
||||
|
@ -1,8 +1,6 @@
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
fn simpleGenericFn() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "simpleGenericFn" {
|
||||
assert(max(i32, 3, -1) == 3);
|
||||
assert(max(f32, 0.123, 0.456) == 0.456);
|
||||
assert(add(2, 3) == 5);
|
||||
@ -17,8 +15,7 @@ fn add(comptime a: i32, b: i32) -> i32 {
|
||||
}
|
||||
|
||||
const the_max = max(u32, 1234, 5678);
|
||||
fn compileTimeGenericEval() {
|
||||
@setFnTest(this);
|
||||
test "compileTimeGenericEval" {
|
||||
assert(the_max == 5678);
|
||||
}
|
||||
|
||||
@ -34,18 +31,14 @@ fn sameButWithFloats(a: f64, b: f64) -> f64 {
|
||||
max(f64, a, b)
|
||||
}
|
||||
|
||||
fn fnWithInlineArgs() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "fnWithInlineArgs" {
|
||||
assert(gimmeTheBigOne(1234, 5678) == 5678);
|
||||
assert(shouldCallSameInstance(34, 12) == 34);
|
||||
assert(sameButWithFloats(0.43, 0.49) == 0.49);
|
||||
}
|
||||
|
||||
|
||||
fn varParams() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "varParams" {
|
||||
assert(max_i32(12, 34) == 34);
|
||||
assert(max_f64(1.2, 3.4) == 3.4);
|
||||
}
|
||||
@ -79,9 +72,7 @@ pub fn SmallList(comptime T: type, comptime STATIC_SIZE: usize) -> type {
|
||||
}
|
||||
}
|
||||
|
||||
fn functionWithReturnTypeType() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "functionWithReturnTypeType" {
|
||||
var list: List(i32) = undefined;
|
||||
var list2: List(i32) = undefined;
|
||||
list.length = 10;
|
||||
@ -91,9 +82,7 @@ fn functionWithReturnTypeType() {
|
||||
}
|
||||
|
||||
|
||||
fn genericStruct() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "genericStruct" {
|
||||
var a1 = GenNode(i32) {.value = 13, .next = null,};
|
||||
var b1 = GenNode(bool) {.value = true, .next = null,};
|
||||
assert(a1.value == 13);
|
||||
@ -108,9 +97,7 @@ fn GenNode(comptime T: type) -> type {
|
||||
}
|
||||
}
|
||||
|
||||
fn constDeclsInStruct() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "constDeclsInStruct" {
|
||||
assert(GenericDataThing(3).count_plus_one == 4);
|
||||
}
|
||||
fn GenericDataThing(comptime count: isize) -> type {
|
||||
@ -120,9 +107,7 @@ fn GenericDataThing(comptime count: isize) -> type {
|
||||
}
|
||||
|
||||
|
||||
fn useGenericParamInGenericParam() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "useGenericParamInGenericParam" {
|
||||
assert(aGenericFn(i32, 3, 4) == 7);
|
||||
}
|
||||
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 {
|
||||
}
|
||||
|
||||
|
||||
fn genericFnWithImplicitCast() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "genericFnWithImplicitCast" {
|
||||
assert(getFirstByte(u8, []u8 {13}) == 13);
|
||||
assert(getFirstByte(u16, []u16 {0, 13}) == 0);
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
fn gotoAndLabels() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "gotoAndLabels" {
|
||||
gotoLoop();
|
||||
assert(goto_counter == 10);
|
||||
}
|
||||
@ -21,9 +19,7 @@ var goto_counter: i32 = 0;
|
||||
|
||||
|
||||
|
||||
fn gotoLeaveDeferScope() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "gotoLeaveDeferScope" {
|
||||
testGotoLeaveDeferScope(true);
|
||||
}
|
||||
fn testGotoLeaveDeferScope(b: bool) {
|
||||
|
@ -1,8 +1,6 @@
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
fn ifStatements() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "ifStatements" {
|
||||
shouldBeEqual(1, 1);
|
||||
firstEqlThird(2, 1, 2);
|
||||
}
|
||||
@ -26,9 +24,7 @@ fn firstEqlThird(a: i32, b: i32, c: i32) {
|
||||
}
|
||||
|
||||
|
||||
fn elseIfExpression() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "elseIfExpression" {
|
||||
assert(elseIfExpressionF(1) == 1);
|
||||
}
|
||||
fn elseIfExpressionF(c: u8) -> u8 {
|
||||
|
@ -1,8 +1,6 @@
|
||||
const assert = @import("std").debug.assert;
|
||||
const a_namespace = @import("cases/import/a_namespace.zig");
|
||||
|
||||
fn callFnViaNamespaceLookup() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "callFnViaNamespaceLookup" {
|
||||
assert(a_namespace.foo() == 1234);
|
||||
}
|
||||
|
@ -15,9 +15,7 @@ fn getErrInt() -> %i32 { 0 }
|
||||
|
||||
error ItBroke;
|
||||
|
||||
fn irBlockDeps() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "irBlockDeps" {
|
||||
assert(%%foo(1) == 0);
|
||||
assert(%%foo(2) == 0);
|
||||
}
|
||||
|
@ -1,60 +1,46 @@
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
fn exactDivision() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "exactDivision" {
|
||||
assert(divExact(55, 11) == 5);
|
||||
}
|
||||
fn divExact(a: u32, b: u32) -> u32 {
|
||||
@divExact(a, b)
|
||||
}
|
||||
|
||||
fn floatDivision() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "floatDivision" {
|
||||
assert(fdiv32(12.0, 3.0) == 4.0);
|
||||
}
|
||||
fn fdiv32(a: f32, b: f32) -> f32 {
|
||||
a / b
|
||||
}
|
||||
|
||||
fn overflowIntrinsics() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "overflowIntrinsics" {
|
||||
var result: u8 = undefined;
|
||||
assert(@addWithOverflow(u8, 250, 100, &result));
|
||||
assert(!@addWithOverflow(u8, 100, 150, &result));
|
||||
assert(result == 250);
|
||||
}
|
||||
|
||||
fn shlWithOverflow() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "shlWithOverflow" {
|
||||
var result: u16 = undefined;
|
||||
assert(@shlWithOverflow(u16, 0b0010111111111111, 3, &result));
|
||||
assert(!@shlWithOverflow(u16, 0b0010111111111111, 2, &result));
|
||||
assert(result == 0b1011111111111100);
|
||||
}
|
||||
|
||||
fn countLeadingZeroes() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "countLeadingZeroes" {
|
||||
assert(@clz(u8(0b00001010)) == 4);
|
||||
assert(@clz(u8(0b10001010)) == 0);
|
||||
assert(@clz(u8(0b00000000)) == 8);
|
||||
}
|
||||
|
||||
fn countTrailingZeroes() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "countTrailingZeroes" {
|
||||
assert(@ctz(u8(0b10100000)) == 5);
|
||||
assert(@ctz(u8(0b10001010)) == 1);
|
||||
assert(@ctz(u8(0b00000000)) == 8);
|
||||
}
|
||||
|
||||
fn modifyOperators() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "modifyOperators" {
|
||||
var i : i32 = 0;
|
||||
i += 5; assert(i == 5);
|
||||
i -= 2; assert(i == 3);
|
||||
@ -70,9 +56,7 @@ fn modifyOperators() {
|
||||
i |= 3; assert(i == 7);
|
||||
}
|
||||
|
||||
fn threeExprInARow() {
|
||||
@setFnTest(this);
|
||||
testThreeExprInARow(false, true);
|
||||
test "threeExprInARow" {
|
||||
}
|
||||
fn testThreeExprInARow(f: bool, t: bool) {
|
||||
assertFalse(f || f || f);
|
||||
@ -94,9 +78,7 @@ fn assertFalse(b: bool) {
|
||||
}
|
||||
|
||||
|
||||
fn constNumberLiteral() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "constNumberLiteral" {
|
||||
const one = 1;
|
||||
const eleven = ten + one;
|
||||
|
||||
@ -106,9 +88,7 @@ const ten = 10;
|
||||
|
||||
|
||||
|
||||
fn unsignedWrapping() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "unsignedWrapping" {
|
||||
testUnsignedWrappingEval(@maxValue(u32));
|
||||
}
|
||||
fn testUnsignedWrappingEval(x: u32) {
|
||||
@ -118,9 +98,7 @@ fn testUnsignedWrappingEval(x: u32) {
|
||||
assert(orig == @maxValue(u32));
|
||||
}
|
||||
|
||||
fn signedWrapping() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "signedWrapping" {
|
||||
testSignedWrappingEval(@maxValue(i32));
|
||||
}
|
||||
fn testSignedWrappingEval(x: i32) {
|
||||
@ -130,9 +108,7 @@ fn testSignedWrappingEval(x: i32) {
|
||||
assert(max_val == @maxValue(i32));
|
||||
}
|
||||
|
||||
fn negationWrapping() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "negationWrapping" {
|
||||
testNegationWrappingEval(@minValue(i16));
|
||||
}
|
||||
fn testNegationWrappingEval(x: i16) {
|
||||
@ -141,9 +117,7 @@ fn testNegationWrappingEval(x: i16) {
|
||||
assert(neg == -32768);
|
||||
}
|
||||
|
||||
fn shlWrapping() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "shlWrapping" {
|
||||
testShlWrappingEval(@maxValue(u16));
|
||||
}
|
||||
fn testShlWrappingEval(x: u16) {
|
||||
@ -151,9 +125,7 @@ fn testShlWrappingEval(x: u16) {
|
||||
assert(shifted == 65534);
|
||||
}
|
||||
|
||||
fn unsigned64BitDivision() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "unsigned64BitDivision" {
|
||||
const result = div(1152921504606846976, 34359738365);
|
||||
assert(result.quotient == 33554432);
|
||||
assert(result.remainder == 100663296);
|
||||
@ -169,9 +141,7 @@ const DivResult = struct {
|
||||
remainder: u64,
|
||||
};
|
||||
|
||||
fn binaryNot() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "binaryNot" {
|
||||
assert(comptime {~u16(0b1010101010101010) == 0b0101010101010101});
|
||||
assert(comptime {~u64(2147483647) == 18446744071562067968});
|
||||
testBinaryNot(0b1010101010101010);
|
||||
@ -181,9 +151,7 @@ fn testBinaryNot(x: u16) {
|
||||
assert(~x == 0b0101010101010101);
|
||||
}
|
||||
|
||||
fn smallIntAddition() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "smallIntAddition" {
|
||||
var x: @intType(false, 2) = 0;
|
||||
assert(x == 0);
|
||||
|
||||
@ -202,9 +170,7 @@ fn smallIntAddition() {
|
||||
assert(result == 0);
|
||||
}
|
||||
|
||||
fn testFloatEquality() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "testFloatEquality" {
|
||||
const x: f64 = 0.012;
|
||||
const y: f64 = x + 1.0;
|
||||
|
||||
|
@ -5,23 +5,21 @@ const cstr = @import("std").cstr;
|
||||
// normal comment
|
||||
/// this is a documentation comment
|
||||
/// doc comment line 2
|
||||
fn emptyFunctionWithComments() {
|
||||
@setFnTest(this);
|
||||
fn emptyFunctionWithComments() {}
|
||||
|
||||
test "emptyFunctionWithComments" {
|
||||
emptyFunctionWithComments();
|
||||
}
|
||||
|
||||
export fn disabledExternFn() {
|
||||
@setFnVisible(this, false);
|
||||
}
|
||||
|
||||
fn callDisabledExternFn() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "callDisabledExternFn" {
|
||||
disabledExternFn();
|
||||
}
|
||||
|
||||
fn intTypeBuiltin() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "intTypeBuiltin" {
|
||||
assert(@intType(true, 8) == i8);
|
||||
assert(@intType(true, 16) == i16);
|
||||
assert(@intType(true, 32) == i32);
|
||||
@ -55,9 +53,7 @@ const u63 = @intType(false, 63);
|
||||
const i1 = @intType(true, 1);
|
||||
const i63 = @intType(true, 63);
|
||||
|
||||
fn minValueAndMaxValue() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "minValueAndMaxValue" {
|
||||
assert(@maxValue(u1) == 1);
|
||||
assert(@maxValue(u8) == 255);
|
||||
assert(@maxValue(u16) == 65535);
|
||||
@ -86,9 +82,7 @@ fn minValueAndMaxValue() {
|
||||
assert(@minValue(i64) == -9223372036854775808);
|
||||
}
|
||||
|
||||
fn maxValueType() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "maxValueType" {
|
||||
// If the type of @maxValue(i32) was i32 then this implicit cast to
|
||||
// u32 would not work. But since the value is a number literal,
|
||||
// it works fine.
|
||||
@ -96,8 +90,7 @@ fn maxValueType() {
|
||||
assert(x == 2147483647);
|
||||
}
|
||||
|
||||
fn shortCircuit() {
|
||||
@setFnTest(this);
|
||||
test "shortCircuit" {
|
||||
testShortCircuit(false, true);
|
||||
}
|
||||
|
||||
@ -128,18 +121,14 @@ fn testShortCircuit(f: bool, t: bool) {
|
||||
assert(hit_4);
|
||||
}
|
||||
|
||||
fn truncate() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "truncate" {
|
||||
assert(testTruncate(0x10fd) == 0xfd);
|
||||
}
|
||||
fn testTruncate(x: u32) -> u8 {
|
||||
@truncate(u8, x)
|
||||
}
|
||||
|
||||
fn assignToIfVarPtr() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "assignToIfVarPtr" {
|
||||
var maybe_bool: ?bool = true;
|
||||
|
||||
if (const *b ?= maybe_bool) {
|
||||
@ -153,27 +142,21 @@ fn first4KeysOfHomeRow() -> []const u8 {
|
||||
"aoeu"
|
||||
}
|
||||
|
||||
fn ReturnStringFromFunction() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "ReturnStringFromFunction" {
|
||||
assert(mem.eql(u8, first4KeysOfHomeRow(), "aoeu"));
|
||||
}
|
||||
|
||||
const g1 : i32 = 1233 + 1;
|
||||
var g2 : i32 = 0;
|
||||
|
||||
fn globalVariables() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "globalVariables" {
|
||||
assert(g2 == 0);
|
||||
g2 = g1;
|
||||
assert(g2 == 1234);
|
||||
}
|
||||
|
||||
|
||||
fn memcpyAndMemsetIntrinsics() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "memcpyAndMemsetIntrinsics" {
|
||||
var foo : [20]u8 = undefined;
|
||||
var bar : [20]u8 = undefined;
|
||||
|
||||
@ -183,16 +166,12 @@ fn memcpyAndMemsetIntrinsics() {
|
||||
if (bar[11] != 'A') @unreachable();
|
||||
}
|
||||
|
||||
fn builtinStaticEval() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "builtinStaticEval" {
|
||||
const x : i32 = comptime {1 + 2 + 3};
|
||||
assert(x == comptime 6);
|
||||
}
|
||||
|
||||
fn slicing() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "slicing" {
|
||||
var array : [20]i32 = undefined;
|
||||
|
||||
array[5] = 1234;
|
||||
@ -209,9 +188,7 @@ fn slicing() {
|
||||
}
|
||||
|
||||
|
||||
fn constantEqualFunctionPointers() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "constantEqualFunctionPointers" {
|
||||
const alias = emptyFn;
|
||||
assert(comptime {emptyFn == alias});
|
||||
}
|
||||
@ -219,27 +196,19 @@ fn constantEqualFunctionPointers() {
|
||||
fn emptyFn() {}
|
||||
|
||||
|
||||
fn hexEscape() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "hexEscape" {
|
||||
assert(mem.eql(u8, "\x68\x65\x6c\x6c\x6f", "hello"));
|
||||
}
|
||||
|
||||
fn stringConcatenation() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "stringConcatenation" {
|
||||
assert(mem.eql(u8, "OK" ++ " IT " ++ "WORKED", "OK IT WORKED"));
|
||||
}
|
||||
|
||||
fn arrayMultOperator() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "arrayMultOperator" {
|
||||
assert(mem.eql(u8, "ab" ** 5, "ababababab"));
|
||||
}
|
||||
|
||||
fn stringEscapes() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "stringEscapes" {
|
||||
assert(mem.eql(u8, "\"", "\x22"));
|
||||
assert(mem.eql(u8, "\'", "\x27"));
|
||||
assert(mem.eql(u8, "\n", "\x0a"));
|
||||
@ -249,9 +218,7 @@ fn stringEscapes() {
|
||||
assert(mem.eql(u8, "\u1234\u0069", "\xe1\x88\xb4\x69"));
|
||||
}
|
||||
|
||||
fn multilineString() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "multilineString" {
|
||||
const s1 =
|
||||
\\one
|
||||
\\two)
|
||||
@ -261,9 +228,7 @@ fn multilineString() {
|
||||
assert(mem.eql(u8, s1, s2));
|
||||
}
|
||||
|
||||
fn multilineCString() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "multilineCString" {
|
||||
const s1 =
|
||||
c\\one
|
||||
c\\two)
|
||||
@ -274,9 +239,7 @@ fn multilineCString() {
|
||||
}
|
||||
|
||||
|
||||
fn typeEquality() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "typeEquality" {
|
||||
assert(&const u8 != &u8);
|
||||
}
|
||||
|
||||
@ -284,22 +247,17 @@ fn typeEquality() {
|
||||
const global_a: i32 = 1234;
|
||||
const global_b: &const i32 = &global_a;
|
||||
const global_c: &const f32 = (&const f32)(global_b);
|
||||
fn compileTimeGlobalReinterpret() {
|
||||
@setFnTest(this);
|
||||
test "compileTimeGlobalReinterpret" {
|
||||
const d = (&const i32)(global_c);
|
||||
assert(*d == 1234);
|
||||
}
|
||||
|
||||
fn explicitCastMaybePointers() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "explicitCastMaybePointers" {
|
||||
const a: ?&i32 = undefined;
|
||||
const b: ?&f32 = (?&f32)(a);
|
||||
}
|
||||
|
||||
fn genericMallocFree() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "genericMallocFree" {
|
||||
const a = %%memAlloc(u8, 10);
|
||||
memFree(u8, a);
|
||||
}
|
||||
@ -310,9 +268,7 @@ fn memAlloc(comptime T: type, n: usize) -> %[]T {
|
||||
fn memFree(comptime T: type, memory: []T) { }
|
||||
|
||||
|
||||
fn castUndefined() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "castUndefined" {
|
||||
const array: [100]u8 = undefined;
|
||||
const slice = ([]const u8)(array);
|
||||
testCastUndefined(slice);
|
||||
@ -320,9 +276,7 @@ fn castUndefined() {
|
||||
fn testCastUndefined(x: []const u8) {}
|
||||
|
||||
|
||||
fn castSmallUnsignedToLargerSigned() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "castSmallUnsignedToLargerSigned" {
|
||||
assert(castSmallUnsignedToLargerSigned1(200) == i16(200));
|
||||
assert(castSmallUnsignedToLargerSigned2(9999) == i64(9999));
|
||||
}
|
||||
@ -330,9 +284,7 @@ fn castSmallUnsignedToLargerSigned1(x: u8) -> i16 { x }
|
||||
fn castSmallUnsignedToLargerSigned2(x: u16) -> i64 { x }
|
||||
|
||||
|
||||
fn implicitCastAfterUnreachable() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "implicitCastAfterUnreachable" {
|
||||
assert(outer() == 1234);
|
||||
}
|
||||
fn inner() -> i32 { 1234 }
|
||||
@ -341,9 +293,7 @@ fn outer() -> i64 {
|
||||
}
|
||||
|
||||
|
||||
fn pointerDereferencing() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "pointerDereferencing" {
|
||||
var x = i32(3);
|
||||
const y = &x;
|
||||
|
||||
@ -353,9 +303,7 @@ fn pointerDereferencing() {
|
||||
assert(*y == 4);
|
||||
}
|
||||
|
||||
fn callResultOfIfElseExpression() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "callResultOfIfElseExpression" {
|
||||
assert(mem.eql(u8, f2(true), "a"));
|
||||
assert(mem.eql(u8, f2(false), "b"));
|
||||
}
|
||||
@ -366,9 +314,7 @@ fn fA() -> []const u8 { "a" }
|
||||
fn fB() -> []const u8 { "b" }
|
||||
|
||||
|
||||
fn constExpressionEvalHandlingOfVariables() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "constExpressionEvalHandlingOfVariables" {
|
||||
var x = true;
|
||||
while (x) {
|
||||
x = false;
|
||||
@ -377,9 +323,7 @@ fn constExpressionEvalHandlingOfVariables() {
|
||||
|
||||
|
||||
|
||||
fn constantEnumInitializationWithDifferingSizes() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "constantEnumInitializationWithDifferingSizes" {
|
||||
test3_1(test3_foo);
|
||||
test3_2(test3_bar);
|
||||
}
|
||||
@ -413,18 +357,14 @@ fn test3_2(f: Test3Foo) {
|
||||
}
|
||||
|
||||
|
||||
fn characterLiterals() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "characterLiterals" {
|
||||
assert('\'' == single_quote);
|
||||
}
|
||||
const single_quote = '\'';
|
||||
|
||||
|
||||
|
||||
fn takeAddressOfParameter() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "takeAddressOfParameter" {
|
||||
testTakeAddressOfParameter(12.34);
|
||||
}
|
||||
fn testTakeAddressOfParameter(f: f32) {
|
||||
@ -433,9 +373,7 @@ fn testTakeAddressOfParameter(f: f32) {
|
||||
}
|
||||
|
||||
|
||||
fn intToPtrCast() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "intToPtrCast" {
|
||||
const x = isize(13);
|
||||
const y = (&u8)(x);
|
||||
const z = usize(y);
|
||||
@ -443,9 +381,7 @@ fn intToPtrCast() {
|
||||
}
|
||||
|
||||
|
||||
fn pointerComparison() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "pointerComparison" {
|
||||
const a = ([]const u8)("a");
|
||||
const b = &a;
|
||||
assert(ptrEql(b, b));
|
||||
@ -455,9 +391,7 @@ fn ptrEql(a: &const []const u8, b: &const []const u8) -> bool {
|
||||
}
|
||||
|
||||
|
||||
fn cStringConcatenation() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "cStringConcatenation" {
|
||||
const a = c"OK" ++ c" IT " ++ c"WORKED";
|
||||
const b = c"OK IT WORKED";
|
||||
|
||||
@ -470,9 +404,7 @@ fn cStringConcatenation() {
|
||||
assert(b[len] == 0);
|
||||
}
|
||||
|
||||
fn castSliceToU8Slice() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "castSliceToU8Slice" {
|
||||
assert(@sizeOf(i32) == 4);
|
||||
var big_thing_array = []i32{1, 2, 3, 4};
|
||||
const big_thing_slice: []i32 = big_thing_array[0...];
|
||||
@ -492,9 +424,7 @@ fn castSliceToU8Slice() {
|
||||
assert(bytes[11] == @maxValue(u8));
|
||||
}
|
||||
|
||||
fn pointerToVoidReturnType() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "pointerToVoidReturnType" {
|
||||
%%testPointerToVoidReturnType();
|
||||
}
|
||||
fn testPointerToVoidReturnType() -> %void {
|
||||
@ -507,17 +437,14 @@ fn testPointerToVoidReturnType2() -> &const void {
|
||||
}
|
||||
|
||||
|
||||
fn nonConstPtrToAliasedType() {
|
||||
@setFnTest(this);
|
||||
test "nonConstPtrToAliasedType" {
|
||||
const int = i32;
|
||||
assert(?&int == ?&i32);
|
||||
}
|
||||
|
||||
|
||||
|
||||
fn array2DConstDoublePtr() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "array2DConstDoublePtr" {
|
||||
const rect_2d_vertexes = [][1]f32 {
|
||||
[]f32{1.0},
|
||||
[]f32{2.0},
|
||||
@ -530,9 +457,7 @@ fn testArray2DConstDoublePtr(ptr: &const f32) {
|
||||
assert(ptr[1] == 2.0);
|
||||
}
|
||||
|
||||
fn isInteger() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "isInteger" {
|
||||
comptime {
|
||||
assert(@isInteger(i8));
|
||||
assert(@isInteger(u8));
|
||||
@ -545,9 +470,7 @@ fn isInteger() {
|
||||
}
|
||||
}
|
||||
|
||||
fn isFloat() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "isFloat" {
|
||||
comptime {
|
||||
assert(!@isFloat(i8));
|
||||
assert(!@isFloat(u8));
|
||||
@ -560,9 +483,7 @@ fn isFloat() {
|
||||
}
|
||||
}
|
||||
|
||||
fn canImplicitCast() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "canImplicitCast" {
|
||||
comptime {
|
||||
assert(@canImplicitCast(i64, i32(3)));
|
||||
assert(!@canImplicitCast(i32, f32(1.234)));
|
||||
@ -570,18 +491,14 @@ fn canImplicitCast() {
|
||||
}
|
||||
}
|
||||
|
||||
fn typeName() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "typeName" {
|
||||
comptime {
|
||||
assert(mem.eql(u8, @typeName(i64), "i64"));
|
||||
assert(mem.eql(u8, @typeName(&usize), "&usize"));
|
||||
}
|
||||
}
|
||||
|
||||
fn volatileLoadAndStore() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "volatileLoadAndStore" {
|
||||
var number: i32 = 1234;
|
||||
const ptr = &volatile number;
|
||||
*ptr += 1;
|
||||
|
@ -1,8 +1,6 @@
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
fn namespaceDependsOnCompileVar() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "namespaceDependsOnCompileVar" {
|
||||
if (some_namespace.a_bool) {
|
||||
assert(some_namespace.a_bool);
|
||||
} else {
|
||||
|
@ -1,8 +1,6 @@
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
fn nullableType() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "nullableType" {
|
||||
const x : ?bool = @generatedCode(true);
|
||||
|
||||
if (const y ?= x) {
|
||||
@ -28,9 +26,7 @@ fn nullableType() {
|
||||
assert(num == 13);
|
||||
}
|
||||
|
||||
fn assignToIfVarPtr() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "assignToIfVarPtr" {
|
||||
var maybe_bool: ?bool = true;
|
||||
|
||||
if (const *b ?= maybe_bool) {
|
||||
@ -40,17 +36,13 @@ fn assignToIfVarPtr() {
|
||||
assert(??maybe_bool == false);
|
||||
}
|
||||
|
||||
fn rhsMaybeUnwrapReturn() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "rhsMaybeUnwrapReturn" {
|
||||
const x: ?bool = @generatedCode(true);
|
||||
const y = x ?? return;
|
||||
}
|
||||
|
||||
|
||||
fn maybeReturn() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "maybeReturn" {
|
||||
maybeReturnImpl();
|
||||
comptime maybeReturnImpl();
|
||||
}
|
||||
@ -67,9 +59,7 @@ fn foo(x: ?i32) -> ?bool {
|
||||
}
|
||||
|
||||
|
||||
fn ifVarMaybePointer() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "ifVarMaybePointer" {
|
||||
assert(shouldBeAPlus1(Particle {.a = 14, .b = 1, .c = 1, .d = 1}) == 15);
|
||||
}
|
||||
fn shouldBeAPlus1(p: Particle) -> u64 {
|
||||
@ -90,9 +80,7 @@ const Particle = struct {
|
||||
};
|
||||
|
||||
|
||||
fn nullLiteralOutsideFunction() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "nullLiteralOutsideFunction" {
|
||||
const is_null = here_is_a_null_literal.context == null;
|
||||
assert(is_null);
|
||||
|
||||
@ -107,9 +95,7 @@ const here_is_a_null_literal = SillyStruct {
|
||||
};
|
||||
|
||||
|
||||
fn testNullRuntime() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "testNullRuntime" {
|
||||
testTestNullRuntime(null);
|
||||
}
|
||||
fn testTestNullRuntime(x: ?i32) {
|
||||
@ -117,9 +103,7 @@ fn testTestNullRuntime(x: ?i32) {
|
||||
assert(!(x != null));
|
||||
}
|
||||
|
||||
fn nullableVoid() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "nullableVoid" {
|
||||
nullableVoidImpl();
|
||||
comptime nullableVoidImpl();
|
||||
}
|
||||
|
@ -1,17 +1,13 @@
|
||||
const other = @import("cases/pub_enum/other.zig");
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
fn pubEnum() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "pubEnum" {
|
||||
pubEnumTest(other.APubEnum.Two);
|
||||
}
|
||||
fn pubEnumTest(foo: other.APubEnum) {
|
||||
assert(foo == other.APubEnum.Two);
|
||||
}
|
||||
|
||||
fn castWithImportedSymbol() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "castWithImportedSymbol" {
|
||||
assert(other.size_t(42) == 42);
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
fn sizeofAndTypeOf() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "sizeofAndTypeOf" {
|
||||
const y: @typeOf(x) = 120;
|
||||
assert(@sizeOf(@typeOf(y)) == 2);
|
||||
}
|
||||
|
@ -5,27 +5,25 @@ const StructWithNoFields = struct {
|
||||
};
|
||||
const empty_global_instance = StructWithNoFields {};
|
||||
|
||||
fn callStructStaticMethod() {
|
||||
@setFnTest(this);
|
||||
test "callStructStaticMethod" {
|
||||
const result = StructWithNoFields.add(3, 4);
|
||||
assert(result == 7);
|
||||
}
|
||||
|
||||
test "returnEmptyStructInstance" {
|
||||
_ = returnEmptyStructInstance();
|
||||
}
|
||||
fn returnEmptyStructInstance() -> StructWithNoFields {
|
||||
@setFnTest(this);
|
||||
return empty_global_instance;
|
||||
}
|
||||
|
||||
const should_be_11 = StructWithNoFields.add(5, 6);
|
||||
|
||||
fn invokeStaticMethodInGlobalScope() {
|
||||
@setFnTest(this);
|
||||
test "invokeStaticMethodInGlobalScope" {
|
||||
assert(should_be_11 == 11);
|
||||
}
|
||||
|
||||
fn voidStructFields() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "voidStructFields" {
|
||||
const foo = VoidStructFieldsFoo {
|
||||
.a = void{},
|
||||
.b = 1,
|
||||
@ -41,9 +39,7 @@ const VoidStructFieldsFoo = struct {
|
||||
};
|
||||
|
||||
|
||||
pub fn structs() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "fn" {
|
||||
var foo: StructFoo = undefined;
|
||||
@memset((&u8)(&foo), 0, @sizeOf(StructFoo));
|
||||
foo.a += 1;
|
||||
@ -74,9 +70,7 @@ const Val = struct {
|
||||
x: i32,
|
||||
};
|
||||
|
||||
fn structPointToSelf() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "structPointToSelf" {
|
||||
var root : Node = undefined;
|
||||
root.val.x = 1;
|
||||
|
||||
@ -89,9 +83,7 @@ fn structPointToSelf() {
|
||||
assert(node.next.next.next.val.x == 1);
|
||||
}
|
||||
|
||||
fn structByvalAssign() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "structByvalAssign" {
|
||||
var foo1 : StructFoo = undefined;
|
||||
var foo2 : StructFoo = undefined;
|
||||
|
||||
@ -108,9 +100,7 @@ fn structInitializer() {
|
||||
}
|
||||
|
||||
|
||||
fn fnCallOfStructField() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "fnCallOfStructField" {
|
||||
assert(callStructField(Foo {.ptr = aFunc,}) == 13);
|
||||
}
|
||||
|
||||
@ -125,9 +115,7 @@ fn callStructField(foo: Foo) -> i32 {
|
||||
}
|
||||
|
||||
|
||||
fn storeMemberFunctionInVariable() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "storeMemberFunctionInVariable" {
|
||||
const instance = MemberFnTestFoo { .x = 1234, };
|
||||
const memberFn = MemberFnTestFoo.member;
|
||||
const result = memberFn(instance);
|
||||
@ -139,17 +127,13 @@ const MemberFnTestFoo = struct {
|
||||
};
|
||||
|
||||
|
||||
fn callMemberFunctionDirectly() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "callMemberFunctionDirectly" {
|
||||
const instance = MemberFnTestFoo { .x = 1234, };
|
||||
const result = MemberFnTestFoo.member(instance);
|
||||
assert(result == 1234);
|
||||
}
|
||||
|
||||
fn memberFunctions() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "memberFunctions" {
|
||||
const r = MemberFnRand {.seed = 1234};
|
||||
assert(r.getSeed() == 1234);
|
||||
}
|
||||
@ -160,9 +144,7 @@ const MemberFnRand = struct {
|
||||
}
|
||||
};
|
||||
|
||||
fn returnStructByvalFromFunction() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "returnStructByvalFromFunction" {
|
||||
const bar = makeBar(1234, 5678);
|
||||
assert(bar.y == 5678);
|
||||
}
|
||||
@ -177,9 +159,7 @@ fn makeBar(x: i32, y: i32) -> Bar {
|
||||
}
|
||||
}
|
||||
|
||||
fn emptyStructMethodCall() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "emptyStructMethodCall" {
|
||||
const es = EmptyStruct{};
|
||||
assert(es.method() == 1234);
|
||||
}
|
||||
@ -190,9 +170,7 @@ const EmptyStruct = struct {
|
||||
};
|
||||
|
||||
|
||||
fn returnEmptyStructFromFn() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "returnEmptyStructFromFn" {
|
||||
_ = testReturnEmptyStructFromFn();
|
||||
}
|
||||
const EmptyStruct2 = struct {};
|
||||
@ -200,9 +178,7 @@ fn testReturnEmptyStructFromFn() -> EmptyStruct2 {
|
||||
EmptyStruct2 {}
|
||||
}
|
||||
|
||||
fn passSliceOfEmptyStructToFn() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "passSliceOfEmptyStructToFn" {
|
||||
assert(testPassSliceOfEmptyStructToFn([]EmptyStruct2{ EmptyStruct2{} }) == 1);
|
||||
}
|
||||
fn testPassSliceOfEmptyStructToFn(slice: []const EmptyStruct2) -> usize {
|
||||
@ -214,9 +190,7 @@ const APackedStruct = packed struct {
|
||||
y: u8,
|
||||
};
|
||||
|
||||
fn packedStruct() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "packedStruct" {
|
||||
var foo = APackedStruct {
|
||||
.x = 1,
|
||||
.y = 2,
|
||||
@ -242,9 +216,7 @@ const bit_field_1 = BitField1 {
|
||||
.c = 3,
|
||||
};
|
||||
|
||||
fn bitFieldAccess() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "bitFieldAccess" {
|
||||
var data = bit_field_1;
|
||||
assert(getA(&data) == 1);
|
||||
assert(getB(&data) == 2);
|
||||
@ -282,9 +254,7 @@ const Foo96Bits = packed struct {
|
||||
d: u24,
|
||||
};
|
||||
|
||||
fn packedStruct24Bits() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "packedStruct24Bits" {
|
||||
comptime {
|
||||
assert(@sizeOf(Foo24Bits) == 3);
|
||||
assert(@sizeOf(Foo96Bits) == 12);
|
||||
@ -327,9 +297,7 @@ const FooArray24Bits = packed struct {
|
||||
c: u16,
|
||||
};
|
||||
|
||||
fn packedArray24Bits() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "packedArray24Bits" {
|
||||
comptime {
|
||||
assert(@sizeOf([9]Foo24Bits) == 9 * 3);
|
||||
assert(@sizeOf(FooArray24Bits) == 2 + 2 * 3 + 2);
|
||||
@ -379,9 +347,7 @@ const FooArrayOfAligned = packed struct {
|
||||
a: [2]FooStructAligned,
|
||||
};
|
||||
|
||||
fn alignedArrayOfPackedStruct() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "alignedArrayOfPackedStruct" {
|
||||
comptime {
|
||||
assert(@sizeOf(FooStructAligned) == 2);
|
||||
assert(@sizeOf(FooArrayOfAligned) == 2 * 2);
|
||||
|
@ -5,9 +5,7 @@ const Node = struct {
|
||||
children: []Node,
|
||||
};
|
||||
|
||||
fn structContainsSliceOfItself() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "structContainsSliceOfItself" {
|
||||
var nodes = []Node {
|
||||
Node {
|
||||
.payload = 1,
|
||||
|
@ -1,8 +1,6 @@
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
fn switchWithNumbers() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "switchWithNumbers" {
|
||||
testSwitchWithNumbers(13);
|
||||
}
|
||||
|
||||
@ -15,9 +13,7 @@ fn testSwitchWithNumbers(x: u32) {
|
||||
assert(result);
|
||||
}
|
||||
|
||||
fn switchWithAllRanges() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "switchWithAllRanges" {
|
||||
assert(testSwitchWithAllRanges(50, 3) == 1);
|
||||
assert(testSwitchWithAllRanges(101, 0) == 2);
|
||||
assert(testSwitchWithAllRanges(300, 5) == 3);
|
||||
@ -33,9 +29,7 @@ fn testSwitchWithAllRanges(x: u32, y: u32) -> u32 {
|
||||
}
|
||||
}
|
||||
|
||||
fn implicitComptimeSwitch() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "implicitComptimeSwitch" {
|
||||
const x = 3 + 4;
|
||||
const result = switch (x) {
|
||||
3 => 10,
|
||||
@ -50,9 +44,7 @@ fn implicitComptimeSwitch() {
|
||||
}
|
||||
}
|
||||
|
||||
fn switchOnEnum() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "switchOnEnum" {
|
||||
const fruit = Fruit.Orange;
|
||||
nonConstSwitchOnEnum(fruit);
|
||||
}
|
||||
@ -70,9 +62,7 @@ fn nonConstSwitchOnEnum(fruit: Fruit) {
|
||||
}
|
||||
|
||||
|
||||
fn switchStatement() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "switchStatement" {
|
||||
nonConstSwitch(SwitchStatmentFoo.C);
|
||||
}
|
||||
fn nonConstSwitch(foo: SwitchStatmentFoo) {
|
||||
@ -92,9 +82,7 @@ const SwitchStatmentFoo = enum {
|
||||
};
|
||||
|
||||
|
||||
fn switchProngWithVar() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "switchProngWithVar" {
|
||||
switchProngWithVarFn(SwitchProngWithVarEnum.One {13});
|
||||
switchProngWithVarFn(SwitchProngWithVarEnum.Two {13.0});
|
||||
switchProngWithVarFn(SwitchProngWithVarEnum.Meh);
|
||||
@ -119,9 +107,7 @@ fn switchProngWithVarFn(a: SwitchProngWithVarEnum) {
|
||||
}
|
||||
|
||||
|
||||
fn switchWithMultipleExpressions() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "switchWithMultipleExpressions" {
|
||||
const x = switch (returnsFive()) {
|
||||
1, 2, 3 => 1,
|
||||
4, 5, 6 => 2,
|
||||
@ -149,8 +135,6 @@ fn returnsFalse() -> bool {
|
||||
Number.Three => |x| return x > 12.34,
|
||||
}
|
||||
}
|
||||
fn switchOnConstEnumWithVar() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "switchOnConstEnumWithVar" {
|
||||
assert(!returnsFalse());
|
||||
}
|
||||
|
@ -21,9 +21,7 @@ fn doThing(form_id: u64) -> %FormValue {
|
||||
}
|
||||
}
|
||||
|
||||
fn switchProngReturnsErrorEnum() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "switchProngReturnsErrorEnum" {
|
||||
%%doThing(17);
|
||||
assert(read_count == 1);
|
||||
}
|
||||
|
@ -15,9 +15,7 @@ fn foo(id: u64) -> %FormValue {
|
||||
}
|
||||
}
|
||||
|
||||
fn switchProngImplicitCast() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "switchProngImplicitCast" {
|
||||
const result = switch (%%foo(2)) {
|
||||
FormValue.One => false,
|
||||
FormValue.Two => |x| x,
|
||||
|
@ -28,15 +28,11 @@ fn factorial(x: i32) -> i32 {
|
||||
}
|
||||
}
|
||||
|
||||
fn thisReferToModuleCallPrivateFn() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "thisReferToModuleCallPrivateFn" {
|
||||
assert(module.add(1, 2) == 3);
|
||||
}
|
||||
|
||||
fn thisReferToContainer() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "thisReferToContainer" {
|
||||
var pt = Point(i32) {
|
||||
.x = 12,
|
||||
.y = 34,
|
||||
@ -46,8 +42,6 @@ fn thisReferToContainer() {
|
||||
assert(pt.y == 35);
|
||||
}
|
||||
|
||||
fn thisReferToFn() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "thisReferToFn" {
|
||||
assert(factorial(5) == 120);
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
fn tryOnErrorUnion() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "tryOnErrorUnion" {
|
||||
tryOnErrorUnionImpl();
|
||||
comptime tryOnErrorUnionImpl();
|
||||
|
||||
@ -25,9 +23,7 @@ fn returnsTen() -> %i32 {
|
||||
10
|
||||
}
|
||||
|
||||
fn tryWithoutVars() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "tryWithoutVars" {
|
||||
const result1 = try (failIfTrue(true)) {
|
||||
1
|
||||
} else {
|
||||
|
@ -5,8 +5,6 @@ type int = u8;
|
||||
fn add(a: int, b: int) -> int {
|
||||
a + b
|
||||
}
|
||||
fn typedef() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "typedef" {
|
||||
assert(add(12, 34) == 46);
|
||||
}
|
||||
|
@ -9,9 +9,7 @@ fn initStaticArray() -> [10]i32 {
|
||||
return array;
|
||||
}
|
||||
const static_array = initStaticArray();
|
||||
fn initStaticArrayToUndefined() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "initStaticArrayToUndefined" {
|
||||
assert(static_array[0] == 1);
|
||||
assert(static_array[4] == 2);
|
||||
assert(static_array[7] == 3);
|
||||
@ -37,9 +35,7 @@ fn setFooX(foo: &Foo) {
|
||||
foo.x = 2;
|
||||
}
|
||||
|
||||
fn assignUndefinedToStruct() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "assignUndefinedToStruct" {
|
||||
comptime {
|
||||
var foo: Foo = undefined;
|
||||
setFooX(&foo);
|
||||
@ -52,9 +48,7 @@ fn assignUndefinedToStruct() {
|
||||
}
|
||||
}
|
||||
|
||||
fn assignUndefinedToStructWithMethod() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "assignUndefinedToStructWithMethod" {
|
||||
comptime {
|
||||
var foo: Foo = undefined;
|
||||
foo.setFooXMethod();
|
||||
|
@ -8,9 +8,7 @@ fn add(args: ...) -> i32 {
|
||||
return sum;
|
||||
}
|
||||
|
||||
fn testAddArbitraryArgs() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "testAddArbitraryArgs" {
|
||||
assert(add(i32(1), i32(2), i32(3), i32(4)) == 10);
|
||||
assert(add(i32(1234)) == 1234);
|
||||
assert(add() == 0);
|
||||
@ -20,15 +18,11 @@ fn readFirstVarArg(args: ...) {
|
||||
const value = args[0];
|
||||
}
|
||||
|
||||
fn sendVoidArgToVarArgs() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "sendVoidArgToVarArgs" {
|
||||
readFirstVarArg({});
|
||||
}
|
||||
|
||||
fn testPassArgsDirectly() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "testPassArgsDirectly" {
|
||||
assert(addSomeStuff(i32(1), i32(2), i32(3), i32(4)) == 10);
|
||||
assert(addSomeStuff(i32(1234)) == 1234);
|
||||
assert(addSomeStuff() == 0);
|
||||
|
@ -6,9 +6,7 @@ const Foo = struct {
|
||||
c: void,
|
||||
};
|
||||
|
||||
fn compareVoidWithVoidCompileTimeKnown() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "compareVoidWithVoidCompileTimeKnown" {
|
||||
comptime {
|
||||
const foo = Foo {
|
||||
.a = {},
|
||||
|
@ -1,8 +1,6 @@
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
fn whileLoop() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "whileLoop" {
|
||||
var i : i32 = 0;
|
||||
while (i < 4) {
|
||||
i += 1;
|
||||
@ -18,9 +16,7 @@ fn whileLoop2() -> i32 {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
fn staticEvalWhile() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "staticEvalWhile" {
|
||||
assert(static_eval_while_number == 1);
|
||||
}
|
||||
const static_eval_while_number = staticWhileLoop1();
|
||||
@ -33,9 +29,7 @@ fn staticWhileLoop2() -> i32 {
|
||||
}
|
||||
}
|
||||
|
||||
fn continueAndBreak() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "continueAndBreak" {
|
||||
runContinueAndBreakTest();
|
||||
assert(continue_and_break_counter == 8);
|
||||
}
|
||||
@ -53,9 +47,7 @@ fn runContinueAndBreakTest() {
|
||||
assert(i == 4);
|
||||
}
|
||||
|
||||
fn returnWithImplicitCastFromWhileLoop() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "returnWithImplicitCastFromWhileLoop" {
|
||||
%%returnWithImplicitCastFromWhileLoopTest();
|
||||
}
|
||||
fn returnWithImplicitCastFromWhileLoopTest() -> %void {
|
||||
@ -64,9 +56,7 @@ fn returnWithImplicitCastFromWhileLoopTest() -> %void {
|
||||
}
|
||||
}
|
||||
|
||||
fn whileWithContinueExpr() {
|
||||
@setFnTest(this);
|
||||
|
||||
test "whileWithContinueExpr" {
|
||||
var sum: i32 = 0;
|
||||
{var i: i32 = 0; while (i < 10; i += 1) {
|
||||
if (i == 5) continue;
|
||||
|
@ -14,6 +14,12 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
enum TestSpecial {
|
||||
TestSpecialNone,
|
||||
TestSpecialSelfHosted,
|
||||
TestSpecialStd,
|
||||
};
|
||||
|
||||
struct TestSourceFile {
|
||||
const char *relative_path;
|
||||
const char *source_code;
|
||||
@ -32,7 +38,7 @@ struct TestCase {
|
||||
ZigList<const char *> compiler_args;
|
||||
ZigList<const char *> program_args;
|
||||
bool is_parseh;
|
||||
bool is_self_hosted;
|
||||
TestSpecial special;
|
||||
bool is_release_mode;
|
||||
bool is_debug_safety;
|
||||
AllowWarnings allow_warnings;
|
||||
@ -79,7 +85,6 @@ static TestCase *add_simple_case(const char *case_name, const char *source, cons
|
||||
test_case->compiler_args.append("--strip");
|
||||
test_case->compiler_args.append("--color");
|
||||
test_case->compiler_args.append("on");
|
||||
test_case->compiler_args.append("--check-unused");
|
||||
|
||||
test_cases.append(test_case);
|
||||
|
||||
@ -93,9 +98,10 @@ static TestCase *add_simple_case_libc(const char *case_name, const char *source,
|
||||
return tc;
|
||||
}
|
||||
|
||||
static TestCase *add_compile_fail_case_extra(const char *case_name, const char *source, bool check_unused,
|
||||
size_t count, va_list ap)
|
||||
{
|
||||
static TestCase *add_compile_fail_case(const char *case_name, const char *source, size_t count, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, count);
|
||||
|
||||
TestCase *test_case = allocate<TestCase>(1);
|
||||
test_case->case_name = case_name;
|
||||
test_case->source_files.resize(1);
|
||||
@ -122,31 +128,11 @@ static TestCase *add_compile_fail_case_extra(const char *case_name, const char *
|
||||
test_case->compiler_args.append("--release");
|
||||
test_case->compiler_args.append("--strip");
|
||||
|
||||
if (check_unused) {
|
||||
test_case->compiler_args.append("--check-unused");
|
||||
}
|
||||
|
||||
test_cases.append(test_case);
|
||||
|
||||
return test_case;
|
||||
}
|
||||
|
||||
static TestCase *add_compile_fail_case_no_check_unused(const char *case_name, const char *source, size_t count, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, count);
|
||||
TestCase *result = add_compile_fail_case_extra(case_name, source, false, count, ap);
|
||||
va_end(ap);
|
||||
return result;
|
||||
}
|
||||
|
||||
static TestCase *add_compile_fail_case(const char *case_name, const char *source, size_t count, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, count);
|
||||
TestCase *result = add_compile_fail_case_extra(case_name, source, true, count, ap);
|
||||
va_end(ap);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void add_debug_safety_case(const char *case_name, const char *source) {
|
||||
{
|
||||
TestCase *test_case = allocate<TestCase>(1);
|
||||
@ -674,24 +660,27 @@ static void add_compile_failure_test_cases(void) {
|
||||
add_compile_fail_case("multiple function definitions", R"SOURCE(
|
||||
fn a() {}
|
||||
fn a() {}
|
||||
export fn entry() { a(); }
|
||||
)SOURCE", 1, ".tmp_source.zig:3:1: error: redefinition of 'a'");
|
||||
|
||||
add_compile_fail_case("unreachable with return", R"SOURCE(
|
||||
fn a() -> unreachable {return;}
|
||||
export fn entry() { a(); }
|
||||
)SOURCE", 1, ".tmp_source.zig:2:24: error: expected type 'unreachable', found 'void'");
|
||||
|
||||
add_compile_fail_case("control reaches end of non-void function", R"SOURCE(
|
||||
fn a() -> i32 {}
|
||||
export fn entry() { _ = a(); }
|
||||
)SOURCE", 1, ".tmp_source.zig:2:15: error: expected type 'i32', found 'void'");
|
||||
|
||||
add_compile_fail_case("undefined function call", R"SOURCE(
|
||||
fn a() {
|
||||
export fn a() {
|
||||
b();
|
||||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:3:5: error: use of undeclared identifier 'b'");
|
||||
|
||||
add_compile_fail_case("wrong number of arguments", R"SOURCE(
|
||||
fn a() {
|
||||
export fn a() {
|
||||
b(1);
|
||||
}
|
||||
fn b(a: i32, b: i32, c: i32) { }
|
||||
@ -699,14 +688,16 @@ fn b(a: i32, b: i32, c: i32) { }
|
||||
|
||||
add_compile_fail_case("invalid type", R"SOURCE(
|
||||
fn a() -> bogus {}
|
||||
export fn entry() { _ = a(); }
|
||||
)SOURCE", 1, ".tmp_source.zig:2:11: error: use of undeclared identifier 'bogus'");
|
||||
|
||||
add_compile_fail_case("pointer to unreachable", R"SOURCE(
|
||||
fn a() -> &unreachable {}
|
||||
export fn entry() { _ = a(); }
|
||||
)SOURCE", 1, ".tmp_source.zig:2:12: error: pointer to unreachable not allowed");
|
||||
|
||||
add_compile_fail_case("unreachable code", R"SOURCE(
|
||||
fn a() {
|
||||
export fn a() {
|
||||
return;
|
||||
b();
|
||||
}
|
||||
@ -716,10 +707,11 @@ fn b() {}
|
||||
|
||||
add_compile_fail_case("bad import", R"SOURCE(
|
||||
const bogus = @import("bogus-does-not-exist.zig");
|
||||
export fn entry() { bogus.bogo(); }
|
||||
)SOURCE", 1, ".tmp_source.zig:2:15: error: unable to find 'bogus-does-not-exist.zig'");
|
||||
|
||||
add_compile_fail_case("undeclared identifier", R"SOURCE(
|
||||
fn a() {
|
||||
export fn a() {
|
||||
b +
|
||||
c
|
||||
}
|
||||
@ -730,10 +722,11 @@ fn a() {
|
||||
add_compile_fail_case("parameter redeclaration", R"SOURCE(
|
||||
fn f(a : i32, a : i32) {
|
||||
}
|
||||
export fn entry() { f(1, 2); }
|
||||
)SOURCE", 1, ".tmp_source.zig:2:15: error: redeclaration of variable 'a'");
|
||||
|
||||
add_compile_fail_case("local variable redeclaration", R"SOURCE(
|
||||
fn f() {
|
||||
export fn f() {
|
||||
const a : i32 = 0;
|
||||
const a = 0;
|
||||
}
|
||||
@ -743,71 +736,73 @@ fn f() {
|
||||
fn f(a : i32) {
|
||||
const a = 0;
|
||||
}
|
||||
export fn entry() { f(1); }
|
||||
)SOURCE", 1, ".tmp_source.zig:3:5: error: redeclaration of variable 'a'");
|
||||
|
||||
add_compile_fail_case("variable has wrong type", R"SOURCE(
|
||||
fn f() -> i32 {
|
||||
export fn f() -> i32 {
|
||||
const a = c"a";
|
||||
a
|
||||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:4:5: error: expected type 'i32', found '&const u8'");
|
||||
|
||||
add_compile_fail_case("if condition is bool, not int", R"SOURCE(
|
||||
fn f() {
|
||||
export fn f() {
|
||||
if (0) {}
|
||||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:3:9: error: integer value 0 cannot be implicitly casted to type 'bool'");
|
||||
|
||||
add_compile_fail_case("assign unreachable", R"SOURCE(
|
||||
fn f() {
|
||||
export fn f() {
|
||||
const a = return;
|
||||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:3:5: error: unreachable code");
|
||||
|
||||
add_compile_fail_case("unreachable variable", R"SOURCE(
|
||||
fn f() {
|
||||
export fn f() {
|
||||
const a : unreachable = {};
|
||||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:3:15: error: variable of type 'unreachable' not allowed");
|
||||
|
||||
add_compile_fail_case("unreachable parameter", R"SOURCE(
|
||||
fn f(a : unreachable) {}
|
||||
export fn entry() { f(); }
|
||||
)SOURCE", 1, ".tmp_source.zig:2:10: error: parameter of type 'unreachable' not allowed");
|
||||
|
||||
add_compile_fail_case("bad assignment target", R"SOURCE(
|
||||
fn f() {
|
||||
export fn f() {
|
||||
3 = 3;
|
||||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:3:7: error: cannot assign to constant");
|
||||
|
||||
add_compile_fail_case("assign to constant variable", R"SOURCE(
|
||||
fn f() {
|
||||
export fn f() {
|
||||
const a = 3;
|
||||
a = 4;
|
||||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:4:7: error: cannot assign to constant");
|
||||
|
||||
add_compile_fail_case("use of undeclared identifier", R"SOURCE(
|
||||
fn f() {
|
||||
export fn f() {
|
||||
b = 3;
|
||||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:3:5: error: use of undeclared identifier 'b'");
|
||||
|
||||
add_compile_fail_case("const is a statement, not an expression", R"SOURCE(
|
||||
fn f() {
|
||||
export fn f() {
|
||||
(const a = 0);
|
||||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:3:6: error: invalid token: 'const'");
|
||||
|
||||
add_compile_fail_case("array access of undeclared identifier", R"SOURCE(
|
||||
fn f() {
|
||||
export fn f() {
|
||||
i[i] = i[i];
|
||||
}
|
||||
)SOURCE", 2, ".tmp_source.zig:3:5: error: use of undeclared identifier 'i'",
|
||||
".tmp_source.zig:3:12: error: use of undeclared identifier 'i'");
|
||||
|
||||
add_compile_fail_case("array access of non array", R"SOURCE(
|
||||
fn f() {
|
||||
export fn f() {
|
||||
var bad : bool = undefined;
|
||||
bad[bad] = bad[bad];
|
||||
}
|
||||
@ -815,7 +810,7 @@ fn f() {
|
||||
".tmp_source.zig:4:19: error: array access of non-array type 'bool'");
|
||||
|
||||
add_compile_fail_case("array access with non integer index", R"SOURCE(
|
||||
fn f() {
|
||||
export fn f() {
|
||||
var array = "aoeu";
|
||||
var bad = false;
|
||||
array[bad] = array[bad];
|
||||
@ -828,6 +823,7 @@ const x : i32 = 99;
|
||||
fn f() {
|
||||
x = 1;
|
||||
}
|
||||
export fn entry() { f(); }
|
||||
)SOURCE", 1, ".tmp_source.zig:4:7: error: cannot assign to constant");
|
||||
|
||||
|
||||
@ -836,22 +832,25 @@ fn f(b: bool) {
|
||||
const x : i32 = if (b) { 1 };
|
||||
const y = if (b) { i32(1) };
|
||||
}
|
||||
export fn entry() { f(true); }
|
||||
)SOURCE", 2, ".tmp_source.zig:3:30: error: integer value 1 cannot be implicitly casted to type 'void'",
|
||||
".tmp_source.zig:4:15: error: incompatible types: 'i32' and 'void'");
|
||||
|
||||
add_compile_fail_case("direct struct loop", R"SOURCE(
|
||||
const A = struct { a : A, };
|
||||
export fn entry() -> usize { @sizeOf(A) }
|
||||
)SOURCE", 1, ".tmp_source.zig:2:11: error: struct 'A' contains itself");
|
||||
|
||||
add_compile_fail_case("indirect struct loop", R"SOURCE(
|
||||
const A = struct { b : B, };
|
||||
const B = struct { c : C, };
|
||||
const C = struct { a : A, };
|
||||
export fn entry() -> usize { @sizeOf(A) }
|
||||
)SOURCE", 1, ".tmp_source.zig:2:11: error: struct 'A' contains itself");
|
||||
|
||||
add_compile_fail_case("invalid struct field", R"SOURCE(
|
||||
const A = struct { x : i32, };
|
||||
fn f() {
|
||||
export fn f() {
|
||||
var a : A = undefined;
|
||||
a.foo = 1;
|
||||
const y = a.bar;
|
||||
@ -873,7 +872,9 @@ const A = enum {};
|
||||
add_compile_fail_case("redefinition of global variables", R"SOURCE(
|
||||
var a : i32 = 1;
|
||||
var a : i32 = 2;
|
||||
)SOURCE", 1, ".tmp_source.zig:3:1: error: redeclaration of variable 'a'");
|
||||
)SOURCE", 2,
|
||||
".tmp_source.zig:3:1: error: redefinition of 'a'",
|
||||
".tmp_source.zig:2:1: note: previous definition is here");
|
||||
|
||||
add_compile_fail_case("byvalue struct parameter in exported function", R"SOURCE(
|
||||
const A = struct { x : i32, };
|
||||
@ -893,7 +894,7 @@ const A = struct {
|
||||
y : i32,
|
||||
z : i32,
|
||||
};
|
||||
fn f() {
|
||||
export fn f() {
|
||||
const a = A {
|
||||
.z = 1,
|
||||
.y = 2,
|
||||
@ -909,7 +910,7 @@ const A = struct {
|
||||
y : i32,
|
||||
z : i32,
|
||||
};
|
||||
fn f() {
|
||||
export fn f() {
|
||||
// we want the error on the '{' not the 'A' because
|
||||
// the A could be a complicated expression
|
||||
const a = A {
|
||||
@ -925,7 +926,7 @@ const A = struct {
|
||||
y : i32,
|
||||
z : i32,
|
||||
};
|
||||
fn f() {
|
||||
export fn f() {
|
||||
const a = A {
|
||||
.z = 4,
|
||||
.y = 2,
|
||||
@ -935,19 +936,19 @@ fn f() {
|
||||
)SOURCE", 1, ".tmp_source.zig:11:9: error: no member named 'foo' in 'A'");
|
||||
|
||||
add_compile_fail_case("invalid break expression", R"SOURCE(
|
||||
fn f() {
|
||||
export fn f() {
|
||||
break;
|
||||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:3:5: error: 'break' expression outside loop");
|
||||
|
||||
add_compile_fail_case("invalid continue expression", R"SOURCE(
|
||||
fn f() {
|
||||
export fn f() {
|
||||
continue;
|
||||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:3:5: error: 'continue' expression outside loop");
|
||||
|
||||
add_compile_fail_case("invalid maybe type", R"SOURCE(
|
||||
fn f() {
|
||||
export fn f() {
|
||||
if (const x ?= true) { }
|
||||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:3:20: error: expected nullable type, found 'bool'");
|
||||
@ -956,42 +957,39 @@ fn f() {
|
||||
fn f() -> i32 {
|
||||
i32(return 1)
|
||||
}
|
||||
export fn entry() { _ = f(); }
|
||||
)SOURCE", 1, ".tmp_source.zig:3:8: error: unreachable code");
|
||||
|
||||
add_compile_fail_case("invalid builtin fn", R"SOURCE(
|
||||
fn f() -> @bogus(foo) {
|
||||
}
|
||||
export fn entry() { _ = f(); }
|
||||
)SOURCE", 1, ".tmp_source.zig:2:11: error: invalid builtin function: 'bogus'");
|
||||
|
||||
add_compile_fail_case("top level decl dependency loop", R"SOURCE(
|
||||
const a : @typeOf(b) = 0;
|
||||
const b : @typeOf(a) = 0;
|
||||
export fn entry() {
|
||||
const c = a + b;
|
||||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:2:1: error: 'a' depends on itself");
|
||||
|
||||
add_compile_fail_case("noalias on non pointer param", R"SOURCE(
|
||||
fn f(noalias x: i32) {}
|
||||
export fn entry() { f(1234); }
|
||||
)SOURCE", 1, ".tmp_source.zig:2:6: error: noalias on non-pointer parameter");
|
||||
|
||||
add_compile_fail_case("struct init syntax for array", R"SOURCE(
|
||||
const foo = []u16{.x = 1024,};
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:2:18: error: type '[]u16' does not support struct initialization syntax");
|
||||
|
||||
add_compile_fail_case("type variables must be constant", R"SOURCE(
|
||||
var foo = u8;
|
||||
)SOURCE", 1, ".tmp_source.zig:2:1: error: variable of type 'type' must be constant");
|
||||
|
||||
add_compile_fail_case("variables shadowing types", R"SOURCE(
|
||||
const Foo = struct {};
|
||||
const Bar = struct {};
|
||||
|
||||
fn f(Foo: i32) {
|
||||
var Bar : i32 = undefined;
|
||||
export fn entry() -> foo {
|
||||
return 1;
|
||||
}
|
||||
)SOURCE", 4,
|
||||
".tmp_source.zig:5:6: error: redeclaration of variable 'Foo'",
|
||||
".tmp_source.zig:2:1: note: previous declaration is here",
|
||||
".tmp_source.zig:6:5: error: redeclaration of variable 'Bar'",
|
||||
".tmp_source.zig:3:1: note: previous declaration is here");
|
||||
)SOURCE", 1, ".tmp_source.zig:2:1: error: variable of type 'type' must be constant");
|
||||
|
||||
add_compile_fail_case("multiple else prongs in a switch", R"SOURCE(
|
||||
fn f(x: u32) {
|
||||
@ -1000,28 +998,36 @@ fn f(x: u32) {
|
||||
else => true,
|
||||
else => true,
|
||||
};
|
||||
}
|
||||
export fn entry() {
|
||||
f(1234);
|
||||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:6:9: error: multiple else prongs in switch expression");
|
||||
|
||||
add_compile_fail_case("global variable initializer must be constant expression", R"SOURCE(
|
||||
extern fn foo() -> i32;
|
||||
const x = foo();
|
||||
export fn entry() -> i32 { x }
|
||||
)SOURCE", 1, ".tmp_source.zig:3:11: error: unable to evaluate constant expression");
|
||||
|
||||
add_compile_fail_case("array concatenation with wrong type", R"SOURCE(
|
||||
const src = "aoeu";
|
||||
const derp = usize(1234);
|
||||
const a = derp ++ "foo";
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(a)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:4:11: error: expected array or C string literal, found 'usize'");
|
||||
|
||||
add_compile_fail_case("non compile time array concatenation", R"SOURCE(
|
||||
fn f(s: [10]u8) -> []u8 {
|
||||
s ++ "foo"
|
||||
}
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(f)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:3:5: error: unable to evaluate constant expression");
|
||||
|
||||
add_compile_fail_case("@cImport with bogus include", R"SOURCE(
|
||||
const c = @cImport(@cInclude("bogus.h"));
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(c.bogo)) }
|
||||
)SOURCE", 2, ".tmp_source.zig:2:11: error: C import failed",
|
||||
".h:1:10: note: 'bogus.h' file not found");
|
||||
|
||||
@ -1029,14 +1035,17 @@ const c = @cImport(@cInclude("bogus.h"));
|
||||
const x = 3;
|
||||
const y = &x;
|
||||
fn foo() -> &const i32 { y }
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:4:26: error: expected type '&const i32', found '&const (integer literal)'");
|
||||
|
||||
add_compile_fail_case("integer overflow error", R"SOURCE(
|
||||
const x : u8 = 300;
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(x)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:2:16: error: integer value 300 cannot be implicitly casted to type 'u8'");
|
||||
|
||||
add_compile_fail_case("incompatible number literals", R"SOURCE(
|
||||
const x = 2 == 2.0;
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(x)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:2:11: error: integer value 2 cannot be implicitly casted to type '(float literal)'");
|
||||
|
||||
add_compile_fail_case("missing function call param", R"SOURCE(
|
||||
@ -1061,11 +1070,14 @@ const members = []member_fn_type {
|
||||
fn f(foo: Foo, index: usize) {
|
||||
const result = members[index]();
|
||||
}
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(f)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:21:34: error: expected 1 arguments, found 0");
|
||||
|
||||
add_compile_fail_case("missing function name and param name", R"SOURCE(
|
||||
fn () {}
|
||||
fn f(i32) {}
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(f)) }
|
||||
)SOURCE", 2,
|
||||
".tmp_source.zig:2:1: error: missing function name",
|
||||
".tmp_source.zig:3:6: error: missing parameter name");
|
||||
@ -1075,6 +1087,7 @@ const fns = []fn(){ a, b, c };
|
||||
fn a() -> i32 {0}
|
||||
fn b() -> i32 {1}
|
||||
fn c() -> i32 {2}
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(fns)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:2:21: error: expected type 'fn()', found 'fn() -> i32'");
|
||||
|
||||
add_compile_fail_case("extern function pointer mismatch", R"SOURCE(
|
||||
@ -1082,18 +1095,23 @@ const fns = [](fn(i32)->i32){ a, b, c };
|
||||
pub fn a(x: i32) -> i32 {x + 0}
|
||||
pub fn b(x: i32) -> i32 {x + 1}
|
||||
export fn c(x: i32) -> i32 {x + 2}
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(fns)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:2:37: error: expected type 'fn(i32) -> i32', found 'extern fn(i32) -> i32'");
|
||||
|
||||
|
||||
add_compile_fail_case("implicit cast from f64 to f32", R"SOURCE(
|
||||
const x : f64 = 1.0;
|
||||
const y : f32 = x;
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(y)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:3:17: error: expected type 'f32', found 'f64'");
|
||||
|
||||
|
||||
add_compile_fail_case("colliding invalid top level functions", R"SOURCE(
|
||||
fn func() -> bogus {}
|
||||
fn func() -> bogus {}
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(func)) }
|
||||
)SOURCE", 2,
|
||||
".tmp_source.zig:3:1: error: redefinition of 'func'",
|
||||
".tmp_source.zig:2:14: error: use of undeclared identifier 'bogus'");
|
||||
@ -1101,6 +1119,7 @@ fn func() -> bogus {}
|
||||
|
||||
add_compile_fail_case("bogus compile var", R"SOURCE(
|
||||
const x = @compileVar("bogus");
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(x)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:2:23: error: unrecognized compile variable: 'bogus'");
|
||||
|
||||
|
||||
@ -1110,6 +1129,8 @@ const Foo = struct {
|
||||
};
|
||||
var global_var: usize = 1;
|
||||
fn get() -> usize { global_var }
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(Foo)) }
|
||||
)SOURCE", 3,
|
||||
".tmp_source.zig:6:21: error: unable to evaluate constant expression",
|
||||
".tmp_source.zig:3:12: note: called from here",
|
||||
@ -1121,6 +1142,8 @@ const Foo = struct {
|
||||
field: i32,
|
||||
};
|
||||
const x = Foo {.field = 1} + Foo {.field = 2};
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(x)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:5:28: error: invalid operands to binary expression: 'Foo' and 'Foo'");
|
||||
|
||||
|
||||
@ -1129,6 +1152,11 @@ const lit_int_x = 1 / 0;
|
||||
const lit_float_x = 1.0 / 0.0;
|
||||
const int_x = i32(1) / i32(0);
|
||||
const float_x = f32(1.0) / f32(0.0);
|
||||
|
||||
export fn entry1() -> usize { @sizeOf(@typeOf(lit_int_x)) }
|
||||
export fn entry2() -> usize { @sizeOf(@typeOf(lit_float_x)) }
|
||||
export fn entry3() -> usize { @sizeOf(@typeOf(int_x)) }
|
||||
export fn entry4() -> usize { @sizeOf(@typeOf(float_x)) }
|
||||
)SOURCE", 4,
|
||||
".tmp_source.zig:2:21: error: division by zero is undefined",
|
||||
".tmp_source.zig:3:25: error: division by zero is undefined",
|
||||
@ -1150,16 +1178,22 @@ fn f(n: Number) -> i32 {
|
||||
Number.Three => i32(3),
|
||||
}
|
||||
}
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(f)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:9:5: error: enumeration value 'Number.Four' not handled in switch");
|
||||
|
||||
add_compile_fail_case("normal string with newline", R"SOURCE(
|
||||
const foo = "a
|
||||
b";
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:2:13: error: newline not allowed in string literal");
|
||||
|
||||
add_compile_fail_case("invalid comparison for function pointers", R"SOURCE(
|
||||
fn foo() {}
|
||||
const invalid = foo > foo;
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(invalid)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:3:21: error: operator not allowed for type 'fn()'");
|
||||
|
||||
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; }
|
||||
fn test1(a: i32, b: i32) -> i32 {
|
||||
return foo(a, b);
|
||||
}
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(test1)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:4:16: error: unable to evaluate constant expression");
|
||||
|
||||
add_compile_fail_case("goto jumping into block", R"SOURCE(
|
||||
fn f() {
|
||||
export fn f() {
|
||||
{
|
||||
a_label:
|
||||
}
|
||||
@ -1185,15 +1221,19 @@ fn f(b: bool) {
|
||||
label:
|
||||
}
|
||||
fn derp(){}
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(f)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:3:12: error: no label in scope named 'label'");
|
||||
|
||||
add_compile_fail_case("assign null to non-nullable pointer", R"SOURCE(
|
||||
const a: &u8 = null;
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(a)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:2:16: error: expected type '&u8', found '(null)'");
|
||||
|
||||
add_compile_fail_case("indexing an array of size zero", R"SOURCE(
|
||||
const array = []u8{};
|
||||
fn foo() {
|
||||
export fn foo() {
|
||||
const pointer = &array[0];
|
||||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:4:27: error: index 0 outside array of size 0");
|
||||
@ -1203,12 +1243,16 @@ const y = foo(0);
|
||||
fn foo(x: i32) -> i32 {
|
||||
1 / x
|
||||
}
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(y)) }
|
||||
)SOURCE", 2,
|
||||
".tmp_source.zig:4:7: error: division by zero is undefined",
|
||||
".tmp_source.zig:2:14: note: called from here");
|
||||
|
||||
add_compile_fail_case("branch on undefined value", R"SOURCE(
|
||||
const x = if (undefined) true else false;
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(x)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:2:15: error: use of undefined value");
|
||||
|
||||
|
||||
@ -1217,12 +1261,16 @@ const seventh_fib_number = fibbonaci(7);
|
||||
fn fibbonaci(x: i32) -> i32 {
|
||||
return fibbonaci(x - 1) + fibbonaci(x - 2);
|
||||
}
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(seventh_fib_number)) }
|
||||
)SOURCE", 2,
|
||||
".tmp_source.zig:4:21: error: evaluation exceeded 1000 backwards branches",
|
||||
".tmp_source.zig:4:21: note: called from here");
|
||||
|
||||
add_compile_fail_case("@embedFile with bogus file", R"SOURCE(
|
||||
const resource = @embedFile("bogus.txt");
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(resource)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:2:29: error: unable to find './bogus.txt'");
|
||||
|
||||
|
||||
@ -1232,6 +1280,8 @@ const Foo = struct {
|
||||
};
|
||||
const a = Foo {.x = get_it()};
|
||||
extern fn get_it() -> i32;
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(a)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:5:21: error: unable to evaluate constant expression");
|
||||
|
||||
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 {
|
||||
}
|
||||
var global_side_effect = false;
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(a)) }
|
||||
)SOURCE", 2,
|
||||
".tmp_source.zig:7:24: error: unable to evaluate constant expression",
|
||||
".tmp_source.zig:5:17: note: called from here");
|
||||
|
||||
add_compile_fail_case("undeclared identifier error should mark fn as impure", R"SOURCE(
|
||||
fn foo() {
|
||||
export fn foo() {
|
||||
test_a_thing();
|
||||
}
|
||||
fn test_a_thing() {
|
||||
@ -1269,12 +1320,15 @@ const EnumWithData = enum {
|
||||
fn bad_eql_2(a: EnumWithData, b: EnumWithData) -> bool {
|
||||
a == b
|
||||
}
|
||||
|
||||
export fn entry1() -> usize { @sizeOf(@typeOf(bad_eql_1)) }
|
||||
export fn entry2() -> usize { @sizeOf(@typeOf(bad_eql_2)) }
|
||||
)SOURCE", 2,
|
||||
".tmp_source.zig:3:7: error: operator not allowed for type '[]u8'",
|
||||
".tmp_source.zig:10:7: error: operator not allowed for type 'EnumWithData'");
|
||||
|
||||
add_compile_fail_case("non-const switch number literal", R"SOURCE(
|
||||
fn foo() {
|
||||
export fn foo() {
|
||||
const x = switch (bar()) {
|
||||
1, 2 => 1,
|
||||
3, 4 => 2,
|
||||
@ -1284,18 +1338,17 @@ fn foo() {
|
||||
fn bar() -> i32 {
|
||||
2
|
||||
}
|
||||
|
||||
)SOURCE", 1, ".tmp_source.zig:3:15: error: unable to infer expression type");
|
||||
|
||||
add_compile_fail_case("atomic orderings of cmpxchg - failure stricter than success", R"SOURCE(
|
||||
fn f() {
|
||||
export fn f() {
|
||||
var x: i32 = 1234;
|
||||
while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.Monotonic, AtomicOrder.SeqCst)) {}
|
||||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:4:72: error: failure atomic ordering must be no stricter than success");
|
||||
|
||||
add_compile_fail_case("atomic orderings of cmpxchg - success Monotonic or stricter", R"SOURCE(
|
||||
fn f() {
|
||||
export fn f() {
|
||||
var x: i32 = 1234;
|
||||
while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.Unordered, AtomicOrder.Unordered)) {}
|
||||
}
|
||||
@ -1306,6 +1359,8 @@ const y = neg(-128);
|
||||
fn neg(x: i8) -> i8 {
|
||||
-x
|
||||
}
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(y)) }
|
||||
)SOURCE", 2,
|
||||
".tmp_source.zig:4:5: error: negation caused overflow",
|
||||
".tmp_source.zig:2:14: note: called from here");
|
||||
@ -1315,6 +1370,8 @@ const y = add(65530, 10);
|
||||
fn add(a: u16, b: u16) -> u16 {
|
||||
a + b
|
||||
}
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(y)) }
|
||||
)SOURCE", 2,
|
||||
".tmp_source.zig:4:7: error: operation caused overflow",
|
||||
".tmp_source.zig:2:14: note: called from here");
|
||||
@ -1325,6 +1382,8 @@ const y = sub(10, 20);
|
||||
fn sub(a: u16, b: u16) -> u16 {
|
||||
a - b
|
||||
}
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(y)) }
|
||||
)SOURCE", 2,
|
||||
".tmp_source.zig:4:7: error: operation caused overflow",
|
||||
".tmp_source.zig:2:14: note: called from here");
|
||||
@ -1334,6 +1393,8 @@ const y = mul(300, 6000);
|
||||
fn mul(a: u16, b: u16) -> u16 {
|
||||
a * b
|
||||
}
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(y)) }
|
||||
)SOURCE", 2,
|
||||
".tmp_source.zig:4:7: error: operation caused overflow",
|
||||
".tmp_source.zig:2:14: note: called from here");
|
||||
@ -1343,10 +1404,12 @@ fn f() -> i8 {
|
||||
const x: u32 = 10;
|
||||
@truncate(i8, x)
|
||||
}
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(f)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:4:19: error: expected signed integer type, found 'u32'");
|
||||
|
||||
add_compile_fail_case("%return in function with non error return type", R"SOURCE(
|
||||
fn f() {
|
||||
export fn f() {
|
||||
%return something();
|
||||
}
|
||||
fn something() -> %void { }
|
||||
@ -1361,7 +1424,7 @@ pub fn main(args: [][]u8) { }
|
||||
add_compile_fail_case("invalid pointer for var type", R"SOURCE(
|
||||
extern fn ext() -> usize;
|
||||
var bytes: [ext()]u8 = undefined;
|
||||
fn f() {
|
||||
export fn f() {
|
||||
for (bytes) |*b, i| {
|
||||
*b = u8(i);
|
||||
}
|
||||
@ -1379,10 +1442,11 @@ extern fn foo(comptime x: i32, y: i32) -> i32;
|
||||
fn f() -> i32 {
|
||||
foo(1, 2)
|
||||
}
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(f)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:2:15: error: comptime parameter not allowed in extern function");
|
||||
|
||||
add_compile_fail_case("convert fixed size array to slice with invalid size", R"SOURCE(
|
||||
fn f() {
|
||||
export fn f() {
|
||||
var array: [5]u8 = undefined;
|
||||
var foo = ([]const u32)(array)[0];
|
||||
}
|
||||
@ -1403,7 +1467,7 @@ pub fn SmallList(comptime T: type, comptime STATIC_SIZE: usize) -> type {
|
||||
}
|
||||
}
|
||||
|
||||
fn function_with_return_type_type() {
|
||||
export fn function_with_return_type_type() {
|
||||
var list: List(i32) = undefined;
|
||||
list.length = 10;
|
||||
}
|
||||
@ -1417,6 +1481,7 @@ var self = "aoeu";
|
||||
fn f(m: []const u8) {
|
||||
m.copy(u8, self[0...], m);
|
||||
}
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(f)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:4:6: error: no member named 'copy' in '[]const u8'");
|
||||
|
||||
add_compile_fail_case("wrong number of arguments for method fn call", R"SOURCE(
|
||||
@ -1427,17 +1492,18 @@ fn f(foo: &const Foo) {
|
||||
|
||||
foo.method(1, 2);
|
||||
}
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(f)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:7:15: error: expected 2 arguments, found 3");
|
||||
|
||||
add_compile_fail_case("assign through constant pointer", R"SOURCE(
|
||||
fn f() {
|
||||
export fn f() {
|
||||
var cstr = c"Hat";
|
||||
cstr[0] = 'W';
|
||||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:4:11: error: cannot assign to constant");
|
||||
|
||||
add_compile_fail_case("assign through constant slice", R"SOURCE(
|
||||
pub fn f() {
|
||||
export fn f() {
|
||||
var cstr: []const u8 = "Hat";
|
||||
cstr[0] = 'W';
|
||||
}
|
||||
@ -1451,6 +1517,7 @@ pub fn main(args: [][]bogus) -> %void {}
|
||||
fn foo(blah: []u8) {
|
||||
for (blah) { }
|
||||
}
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:3:5: error: for loop expression missing element parameter");
|
||||
|
||||
add_compile_fail_case("misspelled type with pointer only reference", R"SOURCE(
|
||||
@ -1482,6 +1549,8 @@ fn foo() {
|
||||
jll.init(1234);
|
||||
var jd = JsonNode {.kind = JsonType.JSONArray , .jobject = JsonOA.JSONArray {jll} };
|
||||
}
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:6:16: error: use of undeclared identifier 'JsonList'");
|
||||
|
||||
add_compile_fail_case("method call with first arg type primitive", R"SOURCE(
|
||||
@ -1495,7 +1564,7 @@ const Foo = struct {
|
||||
}
|
||||
};
|
||||
|
||||
fn f() {
|
||||
export fn f() {
|
||||
const derp = Foo.init(3);
|
||||
|
||||
derp.init();
|
||||
@ -1523,7 +1592,7 @@ pub const Allocator = struct {
|
||||
field: i32,
|
||||
};
|
||||
|
||||
fn foo() {
|
||||
export fn foo() {
|
||||
var x = List.init(&global_allocator);
|
||||
x.init();
|
||||
}
|
||||
@ -1533,13 +1602,15 @@ fn foo() {
|
||||
const TINY_QUANTUM_SHIFT = 4;
|
||||
const TINY_QUANTUM_SIZE = 1 << TINY_QUANTUM_SHIFT;
|
||||
var block_aligned_stuff: usize = (4 + TINY_QUANTUM_SIZE) & ~(TINY_QUANTUM_SIZE - 1);
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(block_aligned_stuff)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:4:60: error: unable to perform binary not operation on type '(integer literal)'");
|
||||
|
||||
{
|
||||
TestCase *tc = add_compile_fail_case("multiple files with private function error", R"SOURCE(
|
||||
const foo = @import("foo.zig");
|
||||
|
||||
fn callPrivFunction() {
|
||||
export fn callPrivFunction() {
|
||||
foo.privateFunction();
|
||||
}
|
||||
)SOURCE", 2,
|
||||
@ -1554,13 +1625,15 @@ fn privateFunction() { }
|
||||
add_compile_fail_case("container init with non-type", R"SOURCE(
|
||||
const zero: i32 = 0;
|
||||
const a = zero{1};
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(a)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:3:11: error: expected type, found 'i32'");
|
||||
|
||||
add_compile_fail_case("assign to constant field", R"SOURCE(
|
||||
const Foo = struct {
|
||||
field: i32,
|
||||
};
|
||||
fn derp() {
|
||||
export fn derp() {
|
||||
const f = Foo {.field = 1234,};
|
||||
f.field = 0;
|
||||
}
|
||||
@ -1580,6 +1653,8 @@ fn canFail() -> %void { }
|
||||
pub fn maybeInt() -> ?i32 {
|
||||
return 0;
|
||||
}
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(testTrickyDefer)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:5:11: error: cannot return from defer expression");
|
||||
|
||||
add_compile_fail_case("attempt to access var args out of bounds", R"SOURCE(
|
||||
@ -1590,6 +1665,8 @@ fn add(args: ...) -> i32 {
|
||||
fn foo() -> i32 {
|
||||
add(i32(1234))
|
||||
}
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
|
||||
)SOURCE", 2,
|
||||
".tmp_source.zig:3:19: error: index 1 outside argument list of size 1",
|
||||
".tmp_source.zig:7:8: note: called from here");
|
||||
@ -1606,10 +1683,12 @@ fn add(args: ...) -> i32 {
|
||||
fn bar() -> i32 {
|
||||
add(1, 2, 3, 4)
|
||||
}
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(bar)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:11:9: error: parameter of type '(integer literal)' requires comptime");
|
||||
|
||||
add_compile_fail_case("assign too big number to u16", R"SOURCE(
|
||||
fn foo() {
|
||||
export fn foo() {
|
||||
var vga_mem: u16 = 0xB8000;
|
||||
}
|
||||
)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 = {
|
||||
@setGlobalAlign(some_data, 3);
|
||||
undefined
|
||||
};
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(some_data)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:3:32: error: alignment value must be power of 2");
|
||||
|
||||
add_compile_fail_case("compile log", R"SOURCE(
|
||||
fn foo() {
|
||||
export fn foo() {
|
||||
comptime bar(12, "hi");
|
||||
}
|
||||
fn bar(a: i32, b: []const u8) {
|
||||
@ -1660,9 +1740,11 @@ fn foo(bit_field: &const BitField) -> u3 {
|
||||
fn bar(x: &const u3) -> u3 {
|
||||
return *x;
|
||||
}
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:12:26: error: expected type '&const u3', found '&:3:6 const u3'");
|
||||
|
||||
add_compile_fail_case_no_check_unused("referring to a struct that is invalid without --check-unused", R"SOURCE(
|
||||
add_compile_fail_case("referring to a struct that is invalid", R"SOURCE(
|
||||
const UsbDeviceRequest = struct {
|
||||
Type: u8,
|
||||
};
|
||||
@ -1679,7 +1761,7 @@ fn assert(ok: bool) {
|
||||
".tmp_source.zig:7:20: note: called from here");
|
||||
|
||||
add_compile_fail_case("control flow uses comptime var at runtime", R"SOURCE(
|
||||
fn foo() {
|
||||
export fn foo() {
|
||||
comptime var i = 0;
|
||||
while (i < 5; i += 1) {
|
||||
bar();
|
||||
@ -1692,14 +1774,14 @@ fn bar() { }
|
||||
".tmp_source.zig:4:21: note: compile-time variable assigned here");
|
||||
|
||||
add_compile_fail_case("ignored return value", R"SOURCE(
|
||||
fn foo() {
|
||||
export fn foo() {
|
||||
bar();
|
||||
}
|
||||
fn bar() -> i32 { 0 }
|
||||
)SOURCE", 1, ".tmp_source.zig:3:8: error: return value ignored");
|
||||
|
||||
add_compile_fail_case("integer literal on a non-comptime var", R"SOURCE(
|
||||
fn foo() {
|
||||
export fn foo() {
|
||||
var i = 0;
|
||||
while (i < 10; i += 1) { }
|
||||
}
|
||||
@ -1712,6 +1794,8 @@ pub fn pass(in: []u8) -> []u8 {
|
||||
*out[0] = in[0];
|
||||
return (*out)[0...1];
|
||||
}
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(pass)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:5:5: error: attempt to dereference non pointer type '[10]u8'");
|
||||
|
||||
add_compile_fail_case("pass const ptr to mutable ptr fn", R"SOURCE(
|
||||
@ -1723,6 +1807,8 @@ fn foo() -> bool {
|
||||
fn ptrEql(a: &[]const u8, b: &[]const u8) -> bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
|
||||
)SOURCE", 1, ".tmp_source.zig:5:19: error: expected type '&[]const u8', found '&const []const u8'");
|
||||
}
|
||||
|
||||
@ -2159,23 +2245,69 @@ static void run_self_hosted_test(bool is_release_mode) {
|
||||
}
|
||||
}
|
||||
|
||||
static void run_std_lib_test(bool is_release_mode) {
|
||||
Buf std_index_file = BUF_INIT;
|
||||
os_path_join(buf_create_from_str(ZIG_STD_DIR),
|
||||
buf_create_from_str("index.zig"), &std_index_file);
|
||||
|
||||
Buf zig_stderr = BUF_INIT;
|
||||
Buf zig_stdout = BUF_INIT;
|
||||
ZigList<const char *> args = {0};
|
||||
args.append("test");
|
||||
args.append(buf_ptr(&std_index_file));
|
||||
if (is_release_mode) {
|
||||
args.append("--release");
|
||||
}
|
||||
Termination term;
|
||||
os_exec_process(zig_exe, args, &term, &zig_stderr, &zig_stdout);
|
||||
|
||||
if (term.how != TerminationIdClean || term.code != 0) {
|
||||
printf("\nstd lib tests failed:\n");
|
||||
printf("./zig");
|
||||
for (size_t i = 0; i < args.length; i += 1) {
|
||||
printf(" %s", args.at(i));
|
||||
}
|
||||
printf("\n%s\n", buf_ptr(&zig_stderr));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void add_self_hosted_tests(void) {
|
||||
{
|
||||
TestCase *test_case = allocate<TestCase>(1);
|
||||
test_case->case_name = "self hosted tests (debug)";
|
||||
test_case->is_self_hosted = true;
|
||||
test_case->special = TestSpecialSelfHosted;
|
||||
test_case->is_release_mode = false;
|
||||
test_cases.append(test_case);
|
||||
}
|
||||
{
|
||||
TestCase *test_case = allocate<TestCase>(1);
|
||||
test_case->case_name = "self hosted tests (release)";
|
||||
test_case->is_self_hosted = true;
|
||||
test_case->special = TestSpecialSelfHosted;
|
||||
test_case->is_release_mode = true;
|
||||
test_cases.append(test_case);
|
||||
}
|
||||
}
|
||||
|
||||
static void add_std_lib_tests(void) {
|
||||
{
|
||||
TestCase *test_case = allocate<TestCase>(1);
|
||||
test_case->case_name = "std (debug)";
|
||||
test_case->special = TestSpecialStd;
|
||||
test_case->is_release_mode = false;
|
||||
test_cases.append(test_case);
|
||||
}
|
||||
{
|
||||
TestCase *test_case = allocate<TestCase>(1);
|
||||
test_case->case_name = "std (release)";
|
||||
test_case->special = TestSpecialStd;
|
||||
test_case->is_release_mode = true;
|
||||
test_cases.append(test_case);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void print_compiler_invocation(TestCase *test_case) {
|
||||
printf("%s", zig_exe);
|
||||
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) {
|
||||
}
|
||||
|
||||
static void run_test(TestCase *test_case) {
|
||||
if (test_case->is_self_hosted) {
|
||||
if (test_case->special == TestSpecialSelfHosted) {
|
||||
return run_self_hosted_test(test_case->is_release_mode);
|
||||
} else if (test_case->special == TestSpecialStd) {
|
||||
return run_std_lib_test(test_case->is_release_mode);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < test_case->source_files.length; i += 1) {
|
||||
@ -2366,6 +2500,7 @@ int main(int argc, char **argv) {
|
||||
add_compile_failure_test_cases();
|
||||
add_parseh_test_cases();
|
||||
add_self_hosted_tests();
|
||||
add_std_lib_tests();
|
||||
run_all_tests(reverse);
|
||||
cleanup();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user