mirror of
https://github.com/ziglang/zig.git
synced 2025-12-26 16:13:07 +00:00
New AIR instruction: `optional_payload_ptr_set` It's like `optional_payload_ptr` except it sets the non-null bit. When storing to the payload via a result location that is an optional, `optional_payload_ptr_set` is now emitted. There is a new algorithm in `zirCoerceResultPtr` which stores a dummy value through the result pointer into a temporary block, and then pops off the AIR instructions from the temporary block in order to determine how to transform the result location pointer in case any in-between coercions need to happen. Fixes a couple of behavior tests regarding optionals.
106 lines
2.1 KiB
Zig
106 lines
2.1 KiB
Zig
const std = @import("std");
|
|
const testing = std.testing;
|
|
const expect = testing.expect;
|
|
const expectEqual = testing.expectEqual;
|
|
|
|
test "passing an optional integer as a parameter" {
|
|
const S = struct {
|
|
fn entry() bool {
|
|
var x: i32 = 1234;
|
|
return foo(x);
|
|
}
|
|
|
|
fn foo(x: ?i32) bool {
|
|
return x.? == 1234;
|
|
}
|
|
};
|
|
try expect(S.entry());
|
|
comptime try expect(S.entry());
|
|
}
|
|
|
|
test "self-referential struct through a slice of optional" {
|
|
const S = struct {
|
|
const Node = struct {
|
|
children: []?Node,
|
|
data: ?u8,
|
|
|
|
fn new() Node {
|
|
return Node{
|
|
.children = undefined,
|
|
.data = null,
|
|
};
|
|
}
|
|
};
|
|
};
|
|
|
|
var n = S.Node.new();
|
|
try expect(n.data == null);
|
|
}
|
|
|
|
pub const EmptyStruct = struct {};
|
|
|
|
test "optional pointer to size zero struct" {
|
|
var e = EmptyStruct{};
|
|
var o: ?*EmptyStruct = &e;
|
|
try expect(o != null);
|
|
}
|
|
|
|
test "equality compare optional pointers" {
|
|
try testNullPtrsEql();
|
|
comptime try testNullPtrsEql();
|
|
}
|
|
|
|
fn testNullPtrsEql() !void {
|
|
var number: i32 = 1234;
|
|
|
|
var x: ?*i32 = null;
|
|
var y: ?*i32 = null;
|
|
try expect(x == y);
|
|
y = &number;
|
|
try expect(x != y);
|
|
try expect(x != &number);
|
|
try expect(&number != x);
|
|
x = &number;
|
|
try expect(x == y);
|
|
try expect(x == &number);
|
|
try expect(&number == x);
|
|
}
|
|
|
|
test "optional with void type" {
|
|
const Foo = struct {
|
|
x: ?void,
|
|
};
|
|
var x = Foo{ .x = null };
|
|
try expect(x.x == null);
|
|
}
|
|
|
|
test "address of unwrap optional" {
|
|
const S = struct {
|
|
const Foo = struct {
|
|
a: i32,
|
|
};
|
|
|
|
var global: ?Foo = null;
|
|
|
|
pub fn getFoo() anyerror!*Foo {
|
|
return &global.?;
|
|
}
|
|
};
|
|
S.global = S.Foo{ .a = 1234 };
|
|
const foo = S.getFoo() catch unreachable;
|
|
try expect(foo.a == 1234);
|
|
}
|
|
|
|
test "nested optional field in struct" {
|
|
const S2 = struct {
|
|
y: u8,
|
|
};
|
|
const S1 = struct {
|
|
x: ?S2,
|
|
};
|
|
var s = S1{
|
|
.x = S2{ .y = 127 },
|
|
};
|
|
try expect(s.x.?.y == 127);
|
|
}
|