| author | |
| committer | |
| log | b560f46c871f234a8b2f762c03984eef963f360a |
| tree | 4c82363776185796842c5b4a505444381a77e67e |
| parent | a130eac7857512db50320fb1c64079b0d696885d |
7 files changed, 91 insertions(+), 26 deletions(-)
src/Module.zig+7-2| ... | @@ -3464,11 +3464,16 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool { | ... | @@ -3464,11 +3464,16 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool { |
| 3464 | queue_linker_work = true; | 3464 | queue_linker_work = true; |
| 3465 | } | 3465 | } |
| 3466 | }, | 3466 | }, |
| 3467 | .array, .@"struct", .@"union" => { | 3467 | |
| 3468 | .generic_poison => unreachable, | ||
| 3469 | .unreachable_value => unreachable, | ||
| 3470 | |||
| 3471 | .function => {}, | ||
| 3472 | |||
| 3473 | else => { | ||
| 3468 | log.debug("send global const to linker: {*} ({s})", .{ decl, decl.name }); | 3474 | log.debug("send global const to linker: {*} ({s})", .{ decl, decl.name }); |
| 3469 | queue_linker_work = true; | 3475 | queue_linker_work = true; |
| 3470 | }, | 3476 | }, |
| 3471 | else => {}, | ||
| 3472 | } | 3477 | } |
| 3473 | 3478 | ||
| 3474 | decl.ty = try decl_tv.ty.copy(&decl_arena.allocator); | 3479 | decl.ty = try decl_tv.ty.copy(&decl_arena.allocator); |
src/Sema.zig+4-2| ... | @@ -4800,8 +4800,10 @@ fn zirOptionalPayload( | ... | @@ -4800,8 +4800,10 @@ fn zirOptionalPayload( |
| 4800 | if (val.isNull()) { | 4800 | if (val.isNull()) { |
| 4801 | return sema.fail(block, src, "unable to unwrap null", .{}); | 4801 | return sema.fail(block, src, "unable to unwrap null", .{}); |
| 4802 | } | 4802 | } |
| 4803 | const sub_val = val.castTag(.opt_payload).?.data; | 4803 | if (val.castTag(.opt_payload)) |payload| { |
| 4804 | return sema.addConstant(result_ty, sub_val); | 4804 | return sema.addConstant(result_ty, payload.data); |
| 4805 | } | ||
| 4806 | return sema.addConstant(result_ty, val); | ||
| 4805 | } | 4807 | } |
| 4806 | 4808 | ||
| 4807 | try sema.requireRuntimeBlock(block, src); | 4809 | try sema.requireRuntimeBlock(block, src); |
src/arch/wasm/CodeGen.zig+5| ... | @@ -848,6 +848,11 @@ pub fn gen(self: *Self, ty: Type, val: Value) InnerError!Result { | ... | @@ -848,6 +848,11 @@ pub fn gen(self: *Self, ty: Type, val: Value) InnerError!Result { |
| 848 | try self.emitConstant(val, ty); | 848 | try self.emitConstant(val, ty); |
| 849 | return Result.appended; | 849 | return Result.appended; |
| 850 | }, | 850 | }, |
| 851 | .Bool => { | ||
| 852 | const int_byte: u8 = @boolToInt(val.toBool()); | ||
| 853 | try self.code.append(int_byte); | ||
| 854 | return Result.appended; | ||
| 855 | }, | ||
| 851 | .Struct => { | 856 | .Struct => { |
| 852 | // TODO write the fields for real | 857 | // TODO write the fields for real |
| 853 | const abi_size = try std.math.cast(usize, ty.abiSize(self.target)); | 858 | const abi_size = try std.math.cast(usize, ty.abiSize(self.target)); |
src/codegen.zig+56| ... | @@ -286,6 +286,62 @@ pub fn generateSymbol( | ... | @@ -286,6 +286,62 @@ pub fn generateSymbol( |
| 286 | } | 286 | } |
| 287 | return Result{ .appended = {} }; | 287 | return Result{ .appended = {} }; |
| 288 | }, | 288 | }, |
| 289 | .Enum => { | ||
| 290 | // TODO populate .debug_info for the enum | ||
| 291 | var int_buffer: Value.Payload.U64 = undefined; | ||
| 292 | const int_val = typed_value.enumToInt(&int_buffer); | ||
| 293 | |||
| 294 | const target = bin_file.options.target; | ||
| 295 | const info = typed_value.ty.intInfo(target); | ||
| 296 | if (info.bits <= 8) { | ||
| 297 | const x = @intCast(u8, int_val.toUnsignedInt()); | ||
| 298 | try code.append(x); | ||
| 299 | return Result{ .appended = {} }; | ||
| 300 | } | ||
| 301 | if (info.bits > 64) { | ||
| 302 | return Result{ | ||
| 303 | .fail = try ErrorMsg.create( | ||
| 304 | bin_file.allocator, | ||
| 305 | src_loc, | ||
| 306 | "TODO implement generateSymbol for big int enums ('{}')", | ||
| 307 | .{typed_value.ty}, | ||
| 308 | ), | ||
| 309 | }; | ||
| 310 | } | ||
| 311 | const endian = target.cpu.arch.endian(); | ||
| 312 | switch (info.signedness) { | ||
| 313 | .unsigned => { | ||
| 314 | if (info.bits <= 16) { | ||
| 315 | const x = @intCast(u16, int_val.toUnsignedInt()); | ||
| 316 | mem.writeInt(u16, try code.addManyAsArray(2), x, endian); | ||
| 317 | } else if (info.bits <= 32) { | ||
| 318 | const x = @intCast(u32, int_val.toUnsignedInt()); | ||
| 319 | mem.writeInt(u32, try code.addManyAsArray(4), x, endian); | ||
| 320 | } else { | ||
| 321 | const x = int_val.toUnsignedInt(); | ||
| 322 | mem.writeInt(u64, try code.addManyAsArray(8), x, endian); | ||
| 323 | } | ||
| 324 | }, | ||
| 325 | .signed => { | ||
| 326 | if (info.bits <= 16) { | ||
| 327 | const x = @intCast(i16, int_val.toSignedInt()); | ||
| 328 | mem.writeInt(i16, try code.addManyAsArray(2), x, endian); | ||
| 329 | } else if (info.bits <= 32) { | ||
| 330 | const x = @intCast(i32, int_val.toSignedInt()); | ||
| 331 | mem.writeInt(i32, try code.addManyAsArray(4), x, endian); | ||
| 332 | } else { | ||
| 333 | const x = int_val.toSignedInt(); | ||
| 334 | mem.writeInt(i64, try code.addManyAsArray(8), x, endian); | ||
| 335 | } | ||
| 336 | }, | ||
| 337 | } | ||
| 338 | return Result{ .appended = {} }; | ||
| 339 | }, | ||
| 340 | .Bool => { | ||
| 341 | const x: u8 = @boolToInt(typed_value.val.toBool()); | ||
| 342 | try code.append(x); | ||
| 343 | return Result{ .appended = {} }; | ||
| 344 | }, | ||
| 289 | .Struct => { | 345 | .Struct => { |
| 290 | const field_vals = typed_value.val.castTag(.@"struct").?.data; | 346 | const field_vals = typed_value.val.castTag(.@"struct").?.data; |
| 291 | _ = field_vals; // TODO write the fields for real | 347 | _ = field_vals; // TODO write the fields for real |
src/codegen/c.zig+1-4| ... | @@ -772,10 +772,7 @@ pub const DeclGen = struct { | ... | @@ -772,10 +772,7 @@ pub const DeclGen = struct { |
| 772 | const target = dg.module.getTarget(); | 772 | const target = dg.module.getTarget(); |
| 773 | 773 | ||
| 774 | switch (t.zigTypeTag()) { | 774 | switch (t.zigTypeTag()) { |
| 775 | .NoReturn => { | 775 | .NoReturn, .Void => try w.writeAll("void"), |
| 776 | try w.writeAll("zig_noreturn void"); | ||
| 777 | }, | ||
| 778 | .Void => try w.writeAll("void"), | ||
| 779 | .Bool => try w.writeAll("bool"), | 776 | .Bool => try w.writeAll("bool"), |
| 780 | .Int => { | 777 | .Int => { |
| 781 | switch (t.tag()) { | 778 | switch (t.tag()) { |
test/behavior/optional.zig+18| ... | @@ -118,3 +118,21 @@ fn test_cmp_optional_non_optional() !void { | ... | @@ -118,3 +118,21 @@ fn test_cmp_optional_non_optional() !void { |
| 118 | break :blk2 @as(?f64, 5.0); | 118 | break :blk2 @as(?f64, 5.0); |
| 119 | }; | 119 | }; |
| 120 | } | 120 | } |
| 121 | |||
| 122 | test "unwrap function call with optional pointer return value" { | ||
| 123 | const S = struct { | ||
| 124 | fn entry() !void { | ||
| 125 | try expect(foo().?.* == 1234); | ||
| 126 | try expect(bar() == null); | ||
| 127 | } | ||
| 128 | const global: i32 = 1234; | ||
| 129 | fn foo() ?*const i32 { | ||
| 130 | return &global; | ||
| 131 | } | ||
| 132 | fn bar() ?*i32 { | ||
| 133 | return null; | ||
| 134 | } | ||
| 135 | }; | ||
| 136 | try S.entry(); | ||
| 137 | comptime try S.entry(); | ||
| 138 | } |
test/behavior/optional_stage1.zig-18| ... | @@ -3,24 +3,6 @@ const testing = std.testing; | ... | @@ -3,24 +3,6 @@ const testing = std.testing; |
| 3 | const expect = testing.expect; | 3 | const expect = testing.expect; |
| 4 | const expectEqual = testing.expectEqual; | 4 | const expectEqual = testing.expectEqual; |
| 5 | 5 | ||
| 6 | test "unwrap function call with optional pointer return value" { | ||
| 7 | const S = struct { | ||
| 8 | fn entry() !void { | ||
| 9 | try expect(foo().?.* == 1234); | ||
| 10 | try expect(bar() == null); | ||
| 11 | } | ||
| 12 | const global: i32 = 1234; | ||
| 13 | fn foo() ?*const i32 { | ||
| 14 | return &global; | ||
| 15 | } | ||
| 16 | fn bar() ?*i32 { | ||
| 17 | return null; | ||
| 18 | } | ||
| 19 | }; | ||
| 20 | try S.entry(); | ||
| 21 | comptime try S.entry(); | ||
| 22 | } | ||
| 23 | |||
| 24 | test "nested orelse" { | 6 | test "nested orelse" { |
| 25 | const S = struct { | 7 | const S = struct { |
| 26 | fn entry() !void { | 8 | fn entry() !void { |