| author | |
| committer | |
| log | 2680f9ab48e041108a29271f55a69d9f869461b9 |
| tree | c5f7c0ae8f71c4423373b686fa354751104b6d58 |
| parent | c5f1925bc801c34133437d0d78de6b1d520f9f12 |
| parent | 9bd8b01650f9cf21e601117951711b21aa5fd216 |
9 files changed, 137 insertions(+), 6 deletions(-)
.gitignore+11| ... | @@ -1,3 +1,14 @@ | ... | @@ -1,3 +1,14 @@ |
| 1 | # This file is for zig-specific build artifacts. | ||
| 2 | # If you have OS-specific or editor-specific files to ignore, | ||
| 3 | # such as *.swp or .DS_Store, put those in your global | ||
| 4 | # ~/.gitignore and put this in your ~/.gitconfig: | ||
| 5 | # | ||
| 6 | # [core] | ||
| 7 | # excludesfile = ~/.gitignore | ||
| 8 | # | ||
| 9 | # Cheers! | ||
| 10 | # -andrewrk | ||
| 11 | |||
| 1 | zig-cache/ | 12 | zig-cache/ |
| 2 | build/ | 13 | build/ |
| 3 | build-*/ | 14 | build-*/ |
src/ir.cpp+15-1| ... | @@ -3332,7 +3332,15 @@ static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Sco | ... | @@ -3332,7 +3332,15 @@ static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Sco |
| 3332 | static VariableTableEntry *ir_create_var(IrBuilder *irb, AstNode *node, Scope *scope, Buf *name, | 3332 | static VariableTableEntry *ir_create_var(IrBuilder *irb, AstNode *node, Scope *scope, Buf *name, |
| 3333 | bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstruction *is_comptime) | 3333 | bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstruction *is_comptime) |
| 3334 | { | 3334 | { |
| 3335 | VariableTableEntry *var = create_local_var(irb->codegen, node, scope, name, src_is_const, gen_is_const, is_shadowable, is_comptime); | 3335 | bool is_underscored = name ? buf_eql_str(name, "_") : false; |
| 3336 | VariableTableEntry *var = create_local_var( irb->codegen | ||
| 3337 | , node | ||
| 3338 | , scope | ||
| 3339 | , (is_underscored ? nullptr : name) | ||
| 3340 | , src_is_const | ||
| 3341 | , gen_is_const | ||
| 3342 | , (is_underscored ? true : is_shadowable) | ||
| 3343 | , is_comptime ); | ||
| 3336 | if (is_comptime != nullptr || gen_is_const) { | 3344 | if (is_comptime != nullptr || gen_is_const) { |
| 3337 | var->mem_slot_index = exec_next_mem_slot(irb->exec); | 3345 | var->mem_slot_index = exec_next_mem_slot(irb->exec); |
| 3338 | var->owner_exec = irb->exec; | 3346 | var->owner_exec = irb->exec; |
| ... | @@ -5186,6 +5194,11 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod | ... | @@ -5186,6 +5194,11 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5186 | 5194 | ||
| 5187 | AstNodeVariableDeclaration *variable_declaration = &node->data.variable_declaration; | 5195 | AstNodeVariableDeclaration *variable_declaration = &node->data.variable_declaration; |
| 5188 | 5196 | ||
| 5197 | if (buf_eql_str(variable_declaration->symbol, "_")) { | ||
| 5198 | add_node_error(irb->codegen, node, buf_sprintf("`_` is not a declarable symbol")); | ||
| 5199 | return irb->codegen->invalid_instruction; | ||
| 5200 | } | ||
| 5201 | |||
| 5189 | IrInstruction *type_instruction; | 5202 | IrInstruction *type_instruction; |
| 5190 | if (variable_declaration->type != nullptr) { | 5203 | if (variable_declaration->type != nullptr) { |
| 5191 | type_instruction = ir_gen_node(irb, variable_declaration->type, scope); | 5204 | type_instruction = ir_gen_node(irb, variable_declaration->type, scope); |
| ... | @@ -5198,6 +5211,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod | ... | @@ -5198,6 +5211,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5198 | bool is_shadowable = false; | 5211 | bool is_shadowable = false; |
| 5199 | bool is_const = variable_declaration->is_const; | 5212 | bool is_const = variable_declaration->is_const; |
| 5200 | bool is_extern = variable_declaration->is_extern; | 5213 | bool is_extern = variable_declaration->is_extern; |
| 5214 | |||
| 5201 | IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, | 5215 | IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, |
| 5202 | ir_should_inline(irb->exec, scope) || variable_declaration->is_comptime); | 5216 | ir_should_inline(irb->exec, scope) || variable_declaration->is_comptime); |
| 5203 | VariableTableEntry *var = ir_create_var(irb, node, scope, variable_declaration->symbol, | 5217 | VariableTableEntry *var = ir_create_var(irb, node, scope, variable_declaration->symbol, |
std/os/linux/index.zig+1-1| ... | @@ -999,7 +999,7 @@ pub fn setgroups(size: usize, list: *const u32) usize { | ... | @@ -999,7 +999,7 @@ pub fn setgroups(size: usize, list: *const u32) usize { |
| 999 | } | 999 | } |
| 1000 | 1000 | ||
| 1001 | pub fn getpid() i32 { | 1001 | pub fn getpid() i32 { |
| 1002 | return @bitCast(i32, u32(syscall0(SYS_getpid))); | 1002 | return @bitCast(i32, @truncate(u32, syscall0(SYS_getpid))); |
| 1003 | } | 1003 | } |
| 1004 | 1004 | ||
| 1005 | pub fn sigprocmask(flags: u32, noalias set: *const sigset_t, noalias oldset: ?*sigset_t) usize { | 1005 | pub fn sigprocmask(flags: u32, noalias set: *const sigset_t, noalias oldset: ?*sigset_t) usize { |
std/os/linux/test.zig+4| ... | @@ -3,6 +3,10 @@ const builtin = @import("builtin"); | ... | @@ -3,6 +3,10 @@ const builtin = @import("builtin"); |
| 3 | const linux = std.os.linux; | 3 | const linux = std.os.linux; |
| 4 | const assert = std.debug.assert; | 4 | const assert = std.debug.assert; |
| 5 | 5 | ||
| 6 | test "getpid" { | ||
| 7 | assert(linux.getpid() != 0); | ||
| 8 | } | ||
| 9 | |||
| 6 | test "timer" { | 10 | test "timer" { |
| 7 | const epoll_fd = linux.epoll_create(); | 11 | const epoll_fd = linux.epoll_create(); |
| 8 | var err = linux.getErrno(epoll_fd); | 12 | var err = linux.getErrno(epoll_fd); |
std/rand/index.zig+5-4| ... | @@ -30,7 +30,7 @@ pub const DefaultCsprng = Isaac64; | ... | @@ -30,7 +30,7 @@ pub const DefaultCsprng = Isaac64; |
| 30 | pub const Random = struct { | 30 | pub const Random = struct { |
| 31 | fillFn: fn (r: *Random, buf: []u8) void, | 31 | fillFn: fn (r: *Random, buf: []u8) void, |
| 32 | 32 | ||
| 33 | /// Read random bytes into the specified buffer until fill. | 33 | /// Read random bytes into the specified buffer until full. |
| 34 | pub fn bytes(r: *Random, buf: []u8) void { | 34 | pub fn bytes(r: *Random, buf: []u8) void { |
| 35 | r.fillFn(r, buf); | 35 | r.fillFn(r, buf); |
| 36 | } | 36 | } |
| ... | @@ -48,10 +48,10 @@ pub const Random = struct { | ... | @@ -48,10 +48,10 @@ pub const Random = struct { |
| 48 | } | 48 | } |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | /// Get a random unsigned integer with even distribution between `start` | 51 | /// Return a random integer with even distribution between `start` |
| 52 | /// inclusive and `end` exclusive. | 52 | /// inclusive and `end` exclusive. `start` must be less than `end`. |
| 53 | pub fn range(r: *Random, comptime T: type, start: T, end: T) T { | 53 | pub fn range(r: *Random, comptime T: type, start: T, end: T) T { |
| 54 | assert(start <= end); | 54 | assert(start < end); |
| 55 | if (T.is_signed) { | 55 | if (T.is_signed) { |
| 56 | const uint = @IntType(false, T.bit_count); | 56 | const uint = @IntType(false, T.bit_count); |
| 57 | if (start >= 0 and end >= 0) { | 57 | if (start >= 0 and end >= 0) { |
| ... | @@ -664,6 +664,7 @@ test "Random range" { | ... | @@ -664,6 +664,7 @@ test "Random range" { |
| 664 | testRange(&prng.random, -4, 3); | 664 | testRange(&prng.random, -4, 3); |
| 665 | testRange(&prng.random, -4, -1); | 665 | testRange(&prng.random, -4, -1); |
| 666 | testRange(&prng.random, 10, 14); | 666 | testRange(&prng.random, 10, 14); |
| 667 | // TODO: test that prng.random.range(1, 1) causes an assertion error | ||
| 667 | } | 668 | } |
| 668 | 669 | ||
| 669 | fn testRange(r: *Random, start: i32, end: i32) void { | 670 | fn testRange(r: *Random, start: i32, end: i32) void { |
test/behavior.zig+1| ... | @@ -60,6 +60,7 @@ comptime { | ... | @@ -60,6 +60,7 @@ comptime { |
| 60 | _ = @import("cases/try.zig"); | 60 | _ = @import("cases/try.zig"); |
| 61 | _ = @import("cases/type_info.zig"); | 61 | _ = @import("cases/type_info.zig"); |
| 62 | _ = @import("cases/undefined.zig"); | 62 | _ = @import("cases/undefined.zig"); |
| 63 | _ = @import("cases/underscore.zig"); | ||
| 63 | _ = @import("cases/union.zig"); | 64 | _ = @import("cases/union.zig"); |
| 64 | _ = @import("cases/var_args.zig"); | 65 | _ = @import("cases/var_args.zig"); |
| 65 | _ = @import("cases/void.zig"); | 66 | _ = @import("cases/void.zig"); |
test/cases/underscore.zig created+28| ... | @@ -0,0 +1,28 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const assert = std.debug.assert; | ||
| 3 | |||
| 4 | test "ignore lval with underscore" { | ||
| 5 | _ = false; | ||
| 6 | } | ||
| 7 | |||
| 8 | test "ignore lval with underscore (for loop)" { | ||
| 9 | for ([]void{}) |_, i| { | ||
| 10 | for ([]void{}) |_, j| { | ||
| 11 | break; | ||
| 12 | } | ||
| 13 | break; | ||
| 14 | } | ||
| 15 | } | ||
| 16 | |||
| 17 | test "ignore lval with underscore (while loop)" { | ||
| 18 | while (optionalReturnError()) |_| { | ||
| 19 | while (optionalReturnError()) |_| { | ||
| 20 | break; | ||
| 21 | } else |_| { } | ||
| 22 | break; | ||
| 23 | } else |_| { } | ||
| 24 | } | ||
| 25 | |||
| 26 | fn optionalReturnError() !?u32 { | ||
| 27 | return error.optionalReturnError; | ||
| 28 | } | ||
test/cases/union.zig+14| ... | @@ -297,3 +297,17 @@ test "access a member of tagged union with conflicting enum tag name" { | ... | @@ -297,3 +297,17 @@ test "access a member of tagged union with conflicting enum tag name" { |
| 297 | 297 | ||
| 298 | comptime assert(Bar.A == u8); | 298 | comptime assert(Bar.A == u8); |
| 299 | } | 299 | } |
| 300 | |||
| 301 | test "tagged union initialization with runtime void" { | ||
| 302 | assert(testTaggedUnionInit({})); | ||
| 303 | } | ||
| 304 | |||
| 305 | const TaggedUnionWithAVoid = union(enum) { | ||
| 306 | A, | ||
| 307 | B: i32, | ||
| 308 | }; | ||
| 309 | |||
| 310 | fn testTaggedUnionInit(x: var) bool { | ||
| 311 | const y = TaggedUnionWithAVoid{ .A = x }; | ||
| 312 | return @TagType(TaggedUnionWithAVoid)(y) == TaggedUnionWithAVoid.A; | ||
| 313 | } |
test/compile_errors.zig+58| ... | @@ -22,6 +22,64 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -22,6 +22,64 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 22 | ".tmp_source.zig:3:28: error: @handle() in non-async function", | 22 | ".tmp_source.zig:3:28: error: @handle() in non-async function", |
| 23 | ); | 23 | ); |
| 24 | 24 | ||
| 25 | cases.add( | ||
| 26 | "`_` is not a declarable symbol", | ||
| 27 | \\export fn f1() usize { | ||
| 28 | \\ var _: usize = 2; | ||
| 29 | \\ return _; | ||
| 30 | \\} | ||
| 31 | , | ||
| 32 | ".tmp_source.zig:2:5: error: `_` is not a declarable symbol", | ||
| 33 | ".tmp_source.zig:3:12: error: use of undeclared identifier '_'", | ||
| 34 | ); | ||
| 35 | |||
| 36 | cases.add( | ||
| 37 | "`_` should not be usable inside for", | ||
| 38 | \\export fn returns() void { | ||
| 39 | \\ for ([]void{}) |_, i| { | ||
| 40 | \\ for ([]void{}) |_, j| { | ||
| 41 | \\ return _; | ||
| 42 | \\ } | ||
| 43 | \\ } | ||
| 44 | \\} | ||
| 45 | , | ||
| 46 | ".tmp_source.zig:4:20: error: use of undeclared identifier '_'", | ||
| 47 | ); | ||
| 48 | |||
| 49 | cases.add( | ||
| 50 | "`_` should not be usable inside while", | ||
| 51 | \\export fn returns() void { | ||
| 52 | \\ while (optionalReturn()) |_| { | ||
| 53 | \\ while (optionalReturn()) |_| { | ||
| 54 | \\ return _; | ||
| 55 | \\ } | ||
| 56 | \\ } | ||
| 57 | \\} | ||
| 58 | \\fn optionalReturn() ?u32 { | ||
| 59 | \\ return 1; | ||
| 60 | \\} | ||
| 61 | , | ||
| 62 | ".tmp_source.zig:4:20: error: use of undeclared identifier '_'", | ||
| 63 | ); | ||
| 64 | |||
| 65 | cases.add( | ||
| 66 | "`_` should not be usable inside while else", | ||
| 67 | \\export fn returns() void { | ||
| 68 | \\ while (optionalReturnError()) |_| { | ||
| 69 | \\ while (optionalReturnError()) |_| { | ||
| 70 | \\ return; | ||
| 71 | \\ } else |_| { | ||
| 72 | \\ if (_ == error.optionalReturnError) return; | ||
| 73 | \\ } | ||
| 74 | \\ } | ||
| 75 | \\} | ||
| 76 | \\fn optionalReturnError() !?u32 { | ||
| 77 | \\ return error.optionalReturnError; | ||
| 78 | \\} | ||
| 79 | , | ||
| 80 | ".tmp_source.zig:6:17: error: use of undeclared identifier '_'", | ||
| 81 | ); | ||
| 82 | |||
| 25 | cases.add( | 83 | cases.add( |
| 26 | "while loop body expression ignored", | 84 | "while loop body expression ignored", |
| 27 | \\fn returns() usize { | 85 | \\fn returns() usize { |