Commit ed5a5e2293

Andrew Kelley <andrew@ziglang.org>
2021-10-14 06:43:19
move behavior tests that are passing for stage2
1 parent 0d4a94f
test/behavior/basic.zig
@@ -1,4 +1,5 @@
 const std = @import("std");
+const builtin = @import("builtin");
 const mem = std.mem;
 const expect = std.testing.expect;
 
@@ -192,6 +193,14 @@ fn testMemcpyMemset() !void {
 const OpaqueA = opaque {};
 const OpaqueB = opaque {};
 
+test "opaque types" {
+    try expect(*OpaqueA != *OpaqueB);
+    if (!builtin.zig_is_stage2) {
+        try expect(mem.eql(u8, @typeName(OpaqueA), "OpaqueA"));
+        try expect(mem.eql(u8, @typeName(OpaqueB), "OpaqueB"));
+    }
+}
+
 test "variable is allowed to be a pointer to an opaque type" {
     var x: i32 = 1234;
     _ = hereIsAnOpaqueType(@ptrCast(*OpaqueA, &x));
@@ -200,3 +209,205 @@ fn hereIsAnOpaqueType(ptr: *OpaqueA) *OpaqueA {
     var a = ptr;
     return a;
 }
+
+const global_a: i32 = 1234;
+const global_b: *const i32 = &global_a;
+const global_c: *const f32 = @ptrCast(*const f32, global_b);
+test "compile time global reinterpret" {
+    const d = @ptrCast(*const i32, global_c);
+    try expect(d.* == 1234);
+}
+
+test "cast undefined" {
+    const array: [100]u8 = undefined;
+    const slice = @as([]const u8, &array);
+    testCastUndefined(slice);
+}
+fn testCastUndefined(x: []const u8) void {
+    _ = x;
+}
+
+test "implicit cast after unreachable" {
+    try expect(outer() == 1234);
+}
+fn inner() i32 {
+    return 1234;
+}
+fn outer() i64 {
+    return inner();
+}
+
+test "take address of parameter" {
+    try testTakeAddressOfParameter(12.34);
+}
+fn testTakeAddressOfParameter(f: f32) !void {
+    const f_ptr = &f;
+    try expect(f_ptr.* == 12.34);
+}
+
+test "pointer to void return type" {
+    testPointerToVoidReturnType() catch unreachable;
+}
+fn testPointerToVoidReturnType() anyerror!void {
+    const a = testPointerToVoidReturnType2();
+    return a.*;
+}
+const test_pointer_to_void_return_type_x = void{};
+fn testPointerToVoidReturnType2() *const void {
+    return &test_pointer_to_void_return_type_x;
+}
+
+test "array 2D const double ptr" {
+    const rect_2d_vertexes = [_][1]f32{
+        [_]f32{1.0},
+        [_]f32{2.0},
+    };
+    try testArray2DConstDoublePtr(&rect_2d_vertexes[0][0]);
+}
+
+fn testArray2DConstDoublePtr(ptr: *const f32) !void {
+    const ptr2 = @ptrCast([*]const f32, ptr);
+    try expect(ptr2[0] == 1.0);
+    try expect(ptr2[1] == 2.0);
+}
+
+test "double implicit cast in same expression" {
+    var x = @as(i32, @as(u16, nine()));
+    try expect(x == 9);
+}
+fn nine() u8 {
+    return 9;
+}
+
+test "comptime if inside runtime while which unconditionally breaks" {
+    testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(true);
+    comptime testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(true);
+}
+fn testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(cond: bool) void {
+    while (cond) {
+        if (false) {}
+        break;
+    }
+}
+
+test "implicit comptime while" {
+    while (false) {
+        @compileError("bad");
+    }
+}
+
+fn fnThatClosesOverLocalConst() type {
+    const c = 1;
+    return struct {
+        fn g() i32 {
+            return c;
+        }
+    };
+}
+
+test "function closes over local const" {
+    const x = fnThatClosesOverLocalConst().g();
+    try expect(x == 1);
+}
+
+test "volatile load and store" {
+    var number: i32 = 1234;
+    const ptr = @as(*volatile i32, &number);
+    ptr.* += 1;
+    try expect(ptr.* == 1235);
+}
+
+test "struct inside function" {
+    try testStructInFn();
+    comptime try testStructInFn();
+}
+
+fn testStructInFn() !void {
+    const BlockKind = u32;
+
+    const Block = struct {
+        kind: BlockKind,
+    };
+
+    var block = Block{ .kind = 1234 };
+
+    block.kind += 1;
+
+    try expect(block.kind == 1235);
+}
+
+test "fn call returning scalar optional in equality expression" {
+    try expect(getNull() == null);
+}
+
+fn getNull() ?*i32 {
+    return null;
+}
+
+var global_foo: *i32 = undefined;
+
+test "global variable assignment with optional unwrapping with var initialized to undefined" {
+    const S = struct {
+        var data: i32 = 1234;
+        fn foo() ?*i32 {
+            return &data;
+        }
+    };
+    global_foo = S.foo() orelse {
+        @panic("bad");
+    };
+    try expect(global_foo.* == 1234);
+}
+
+test "peer result location with typed parent, runtime condition, comptime prongs" {
+    const S = struct {
+        fn doTheTest(arg: i32) i32 {
+            const st = Structy{
+                .bleh = if (arg == 1) 1 else 1,
+            };
+
+            if (st.bleh == 1)
+                return 1234;
+            return 0;
+        }
+
+        const Structy = struct {
+            bleh: i32,
+        };
+    };
+    try expect(S.doTheTest(0) == 1234);
+    try expect(S.doTheTest(1) == 1234);
+}
+
+fn ZA() type {
+    return struct {
+        b: B(),
+
+        const Self = @This();
+
+        fn B() type {
+            return struct {
+                const Self = @This();
+            };
+        }
+    };
+}
+test "non-ambiguous reference of shadowed decls" {
+    try expect(ZA().B().Self != ZA().Self);
+}
+
+test "use of declaration with same name as primitive" {
+    const S = struct {
+        const @"u8" = u16;
+        const alias = @"u8";
+    };
+    const a: S.u8 = 300;
+    try expect(a == 300);
+
+    const b: S.alias = 300;
+    try expect(b == 300);
+
+    const @"u8" = u16;
+    const c: @"u8" = 300;
+    try expect(c == 300);
+}
test/behavior/misc.zig
@@ -5,6 +5,8 @@ const expectEqualStrings = std.testing.expectEqualStrings;
 const mem = std.mem;
 const builtin = @import("builtin");
 
+fn emptyFn() void {}
+
 test "constant equal function pointers" {
     const alias = emptyFn;
     try expect(comptime x: {
@@ -12,7 +14,16 @@ test "constant equal function pointers" {
     });
 }
 
-fn emptyFn() void {}
+const addr1 = @ptrCast(*const u8, emptyFn);
+test "comptime cast fn to ptr" {
+    const addr2 = @ptrCast(*const u8, emptyFn);
+    comptime try expect(addr1 == addr2);
+}
+
+test "equality compare fn ptrs" {
+    var a = emptyFn;
+    try expect(a == a);
+}
 
 test "string escapes" {
     try expectEqualStrings("\"", "\x22");
@@ -34,51 +45,12 @@ test "multiline string literal is null terminated" {
     try expect(std.cstr.cmp(s1, s2) == 0);
 }
 
-const global_a: i32 = 1234;
-const global_b: *const i32 = &global_a;
-const global_c: *const f32 = @ptrCast(*const f32, global_b);
-test "compile time global reinterpret" {
-    const d = @ptrCast(*const i32, global_c);
-    try expect(d.* == 1234);
-}
-
 test "explicit cast maybe pointers" {
     const a: ?*i32 = undefined;
     const b: ?*f32 = @ptrCast(?*f32, a);
     _ = b;
 }
 
-test "generic malloc free" {
-    const a = memAlloc(u8, 10) catch unreachable;
-    memFree(u8, a);
-}
-var some_mem: [100]u8 = undefined;
-fn memAlloc(comptime T: type, n: usize) anyerror![]T {
-    return @ptrCast([*]T, &some_mem[0])[0..n];
-}
-fn memFree(comptime T: type, memory: []T) void {
-    _ = memory;
-}
-
-test "cast undefined" {
-    const array: [100]u8 = undefined;
-    const slice = @as([]const u8, &array);
-    testCastUndefined(slice);
-}
-fn testCastUndefined(x: []const u8) void {
-    _ = x;
-}
-
-test "implicit cast after unreachable" {
-    try expect(outer() == 1234);
-}
-fn inner() i32 {
-    return 1234;
-}
-fn outer() i64 {
-    return inner();
-}
-
 test "constant enum initialization with differing sizes" {
     try test3_1(test3_foo);
     try test3_2(test3_bar);
@@ -117,14 +89,6 @@ fn test3_2(f: Test3Foo) !void {
     }
 }
 
-test "take address of parameter" {
-    try testTakeAddressOfParameter(12.34);
-}
-fn testTakeAddressOfParameter(f: f32) !void {
-    const f_ptr = &f;
-    try expect(f_ptr.* == 12.34);
-}
-
 test "pointer comparison" {
     const a = @as([]const u8, "a");
     const b = &a;
@@ -153,40 +117,6 @@ test "string concatenation" {
     try expect(b[len] == 0);
 }
 
-test "pointer to void return type" {
-    testPointerToVoidReturnType() catch unreachable;
-}
-fn testPointerToVoidReturnType() anyerror!void {
-    const a = testPointerToVoidReturnType2();
-    return a.*;
-}
-const test_pointer_to_void_return_type_x = void{};
-fn testPointerToVoidReturnType2() *const void {
-    return &test_pointer_to_void_return_type_x;
-}
-
-test "array 2D const double ptr" {
-    const rect_2d_vertexes = [_][1]f32{
-        [_]f32{1.0},
-        [_]f32{2.0},
-    };
-    try testArray2DConstDoublePtr(&rect_2d_vertexes[0][0]);
-}
-
-fn testArray2DConstDoublePtr(ptr: *const f32) !void {
-    const ptr2 = @ptrCast([*]const f32, ptr);
-    try expect(ptr2[0] == 1.0);
-    try expect(ptr2[1] == 2.0);
-}
-
-test "double implicit cast in same expression" {
-    var x = @as(i32, @as(u16, nine()));
-    try expect(x == 9);
-}
-fn nine() u8 {
-    return 9;
-}
-
 test "global variable initialized to global variable array element" {
     try expect(global_ptr == &gdt[0]);
 }
@@ -206,45 +136,6 @@ export fn writeToVRam() void {
     vram[0] = 'X';
 }
 
-const OpaqueA = opaque {};
-const OpaqueB = opaque {};
-test "opaque types" {
-    try expect(*OpaqueA != *OpaqueB);
-    try expect(mem.eql(u8, @typeName(OpaqueA), "OpaqueA"));
-    try expect(mem.eql(u8, @typeName(OpaqueB), "OpaqueB"));
-}
-
-test "comptime if inside runtime while which unconditionally breaks" {
-    testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(true);
-    comptime testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(true);
-}
-fn testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(cond: bool) void {
-    while (cond) {
-        if (false) {}
-        break;
-    }
-}
-
-test "implicit comptime while" {
-    while (false) {
-        @compileError("bad");
-    }
-}
-
-fn fnThatClosesOverLocalConst() type {
-    const c = 1;
-    return struct {
-        fn g() i32 {
-            return c;
-        }
-    };
-}
-
-test "function closes over local const" {
-    const x = fnThatClosesOverLocalConst().g();
-    try expect(x == 1);
-}
-
 const PackedStruct = packed struct {
     a: u8,
     b: u8,
@@ -268,26 +159,6 @@ export fn testPackedStuff(a: *const PackedStruct, b: *const PackedUnion) void {
     }
 }
 
-test "slicing zero length array" {
-    const s1 = ""[0..];
-    const s2 = ([_]u32{})[0..];
-    try expect(s1.len == 0);
-    try expect(s2.len == 0);
-    try expect(mem.eql(u8, s1, ""));
-    try expect(mem.eql(u32, s2, &[_]u32{}));
-}
-
-const addr1 = @ptrCast(*const u8, emptyFn);
-test "comptime cast fn to ptr" {
-    const addr2 = @ptrCast(*const u8, emptyFn);
-    comptime try expect(addr1 == addr2);
-}
-
-test "equality compare fn ptrs" {
-    var a = emptyFn;
-    try expect(a == a);
-}
-
 test "self reference through fn ptr field" {
     const S = struct {
         const A = struct {
@@ -304,52 +175,6 @@ test "self reference through fn ptr field" {
     try expect(a.f(a) == 12);
 }
 
-test "volatile load and store" {
-    var number: i32 = 1234;
-    const ptr = @as(*volatile i32, &number);
-    ptr.* += 1;
-    try expect(ptr.* == 1235);
-}
-
-test "slice string literal has correct type" {
-    comptime {
-        try expect(@TypeOf("aoeu"[0..]) == *const [4:0]u8);
-        const array = [_]i32{ 1, 2, 3, 4 };
-        try expect(@TypeOf(array[0..]) == *const [4]i32);
-    }
-    var runtime_zero: usize = 0;
-    comptime try expect(@TypeOf("aoeu"[runtime_zero..]) == [:0]const u8);
-    const array = [_]i32{ 1, 2, 3, 4 };
-    comptime try expect(@TypeOf(array[runtime_zero..]) == []const i32);
-}
-
-test "struct inside function" {
-    try testStructInFn();
-    comptime try testStructInFn();
-}
-
-fn testStructInFn() !void {
-    const BlockKind = u32;
-
-    const Block = struct {
-        kind: BlockKind,
-    };
-
-    var block = Block{ .kind = 1234 };
-
-    block.kind += 1;
-
-    try expect(block.kind == 1235);
-}
-
-test "fn call returning scalar optional in equality expression" {
-    try expect(getNull() == null);
-}
-
-fn getNull() ?*i32 {
-    return null;
-}
-
 test "thread local variable" {
     const S = struct {
         threadlocal var t: i32 = 1234;
@@ -358,49 +183,6 @@ test "thread local variable" {
     try expect(S.t == 1235);
 }
 
-test "result location zero sized array inside struct field implicit cast to slice" {
-    const E = struct {
-        entries: []u32,
-    };
-    var foo = E{ .entries = &[_]u32{} };
-    try expect(foo.entries.len == 0);
-}
-
-var global_foo: *i32 = undefined;
-
-test "global variable assignment with optional unwrapping with var initialized to undefined" {
-    const S = struct {
-        var data: i32 = 1234;
-        fn foo() ?*i32 {
-            return &data;
-        }
-    };
-    global_foo = S.foo() orelse {
-        @panic("bad");
-    };
-    try expect(global_foo.* == 1234);
-}
-
-test "peer result location with typed parent, runtime condition, comptime prongs" {
-    const S = struct {
-        fn doTheTest(arg: i32) i32 {
-            const st = Structy{
-                .bleh = if (arg == 1) 1 else 1,
-            };
-
-            if (st.bleh == 1)
-                return 1234;
-            return 0;
-        }
-
-        const Structy = struct {
-            bleh: i32,
-        };
-    };
-    try expect(S.doTheTest(0) == 1234);
-    try expect(S.doTheTest(1) == 1234);
-}
-
 test "nested optional field in struct" {
     const S2 = struct {
         y: u8,
@@ -462,36 +244,3 @@ test "lazy typeInfo value as generic parameter" {
     };
     S.foo(@typeInfo(@TypeOf(.{})));
 }
-
-fn ZA() type {
-    return struct {
-        b: B(),
-
-        const Self = @This();
-
-        fn B() type {
-            return struct {
-                const Self = @This();
-            };
-        }
-    };
-}
-test "non-ambiguous reference of shadowed decls" {
-    try expect(ZA().B().Self != ZA().Self);
-}
-
-test "use of declaration with same name as primitive" {
-    const S = struct {
-        const @"u8" = u16;
-        const alias = @"u8";
-    };
-    const a: S.u8 = 300;
-    try expect(a == 300);
-
-    const b: S.alias = 300;
-    try expect(b == 300);
-
-    const @"u8" = u16;
-    const c: @"u8" = 300;
-    try expect(c == 300);
-}
test/behavior/optional.zig
@@ -2,270 +2,3 @@ const std = @import("std");
 const testing = std.testing;
 const expect = testing.expect;
 const expectEqual = testing.expectEqual;
-
-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 nullable 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 "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 "equality compare optional with non-optional" {
-    try test_cmp_optional_non_optional();
-    comptime try test_cmp_optional_non_optional();
-}
-
-fn test_cmp_optional_non_optional() !void {
-    var ten: i32 = 10;
-    var opt_ten: ?i32 = 10;
-    var five: i32 = 5;
-    var int_n: ?i32 = null;
-
-    try expect(int_n != ten);
-    try expect(opt_ten == ten);
-    try expect(opt_ten != five);
-
-    // test evaluation is always lexical
-    // ensure that the optional isn't always computed before the non-optional
-    var mutable_state: i32 = 0;
-    _ = blk1: {
-        mutable_state += 1;
-        break :blk1 @as(?f64, 10.0);
-    } != blk2: {
-        try expect(mutable_state == 1);
-        break :blk2 @as(f64, 5.0);
-    };
-    _ = blk1: {
-        mutable_state += 1;
-        break :blk1 @as(f64, 10.0);
-    } != blk2: {
-        try expect(mutable_state == 2);
-        break :blk2 @as(?f64, 5.0);
-    };
-}
-
-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 "unwrap function call with optional pointer return value" {
-    const S = struct {
-        fn entry() !void {
-            try expect(foo().?.* == 1234);
-            try expect(bar() == null);
-        }
-        const global: i32 = 1234;
-        fn foo() ?*const i32 {
-            return &global;
-        }
-        fn bar() ?*i32 {
-            return null;
-        }
-    };
-    try S.entry();
-    comptime try S.entry();
-}
-
-test "nested orelse" {
-    const S = struct {
-        fn entry() !void {
-            try expect(func() == null);
-        }
-        fn maybe() ?Foo {
-            return null;
-        }
-        fn func() ?Foo {
-            const x = maybe() orelse
-                maybe() orelse
-                return null;
-            _ = x;
-            unreachable;
-        }
-        const Foo = struct {
-            field: i32,
-        };
-    };
-    try S.entry();
-    comptime try 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);
-}
-
-test "assigning to an unwrapped optional field in an inline loop" {
-    comptime var maybe_pos_arg: ?comptime_int = null;
-    inline for ("ab") |x| {
-        _ = x;
-        maybe_pos_arg = 0;
-        if (maybe_pos_arg.? != 0) {
-            @compileError("bad");
-        }
-        maybe_pos_arg.? = 10;
-    }
-}
-
-test "coerce an anon struct literal to optional struct" {
-    const S = struct {
-        const Struct = struct {
-            field: u32,
-        };
-        fn doTheTest() !void {
-            var maybe_dims: ?Struct = null;
-            maybe_dims = .{ .field = 1 };
-            try expect(maybe_dims.?.field == 1);
-        }
-    };
-    try S.doTheTest();
-    comptime try S.doTheTest();
-}
-
-test "optional with void type" {
-    const Foo = struct {
-        x: ?void,
-    };
-    var x = Foo{ .x = null };
-    try expect(x.x == null);
-}
-
-test "0-bit child type coerced to optional return ptr result location" {
-    const S = struct {
-        fn doTheTest() !void {
-            var y = Foo{};
-            var z = y.thing();
-            try expect(z != null);
-        }
-
-        const Foo = struct {
-            pub const Bar = struct {
-                field: *Foo,
-            };
-
-            pub fn thing(self: *Foo) ?Bar {
-                return Bar{ .field = self };
-            }
-        };
-    };
-    try S.doTheTest();
-    comptime try S.doTheTest();
-}
-
-test "0-bit child type coerced to optional" {
-    const S = struct {
-        fn doTheTest() !void {
-            var it: Foo = .{
-                .list = undefined,
-            };
-            try expect(it.foo() != null);
-        }
-
-        const Empty = struct {};
-        const Foo = struct {
-            list: [10]Empty,
-
-            fn foo(self: *Foo) ?*Empty {
-                const data = &self.list[0];
-                return data;
-            }
-        };
-    };
-    try S.doTheTest();
-    comptime try S.doTheTest();
-}
-
-test "array of optional unaligned types" {
-    const Enum = enum { one, two, three };
-
-    const SomeUnion = union(enum) {
-        Num: Enum,
-        Other: u32,
-    };
-
-    const values = [_]?SomeUnion{
-        SomeUnion{ .Num = .one },
-        SomeUnion{ .Num = .two },
-        SomeUnion{ .Num = .three },
-        SomeUnion{ .Num = .one },
-        SomeUnion{ .Num = .two },
-        SomeUnion{ .Num = .three },
-    };
-
-    // The index must be a runtime value
-    var i: usize = 0;
-    try expectEqual(Enum.one, values[i].?.Num);
-    i += 1;
-    try expectEqual(Enum.two, values[i].?.Num);
-    i += 1;
-    try expectEqual(Enum.three, values[i].?.Num);
-    i += 1;
-    try expectEqual(Enum.one, values[i].?.Num);
-    i += 1;
-    try expectEqual(Enum.two, values[i].?.Num);
-    i += 1;
-    try expectEqual(Enum.three, values[i].?.Num);
-}
test/behavior/optional_stage1.zig
@@ -0,0 +1,284 @@
+const std = @import("std");
+const testing = std.testing;
+const expect = testing.expect;
+const expectEqual = testing.expectEqual;
+
+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 nullable 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 "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 "equality compare optional with non-optional" {
+    try test_cmp_optional_non_optional();
+    comptime try test_cmp_optional_non_optional();
+}
+
+fn test_cmp_optional_non_optional() !void {
+    var ten: i32 = 10;
+    var opt_ten: ?i32 = 10;
+    var five: i32 = 5;
+    var int_n: ?i32 = null;
+
+    try expect(int_n != ten);
+    try expect(opt_ten == ten);
+    try expect(opt_ten != five);
+
+    // test evaluation is always lexical
+    // ensure that the optional isn't always computed before the non-optional
+    var mutable_state: i32 = 0;
+    _ = blk1: {
+        mutable_state += 1;
+        break :blk1 @as(?f64, 10.0);
+    } != blk2: {
+        try expect(mutable_state == 1);
+        break :blk2 @as(f64, 5.0);
+    };
+    _ = blk1: {
+        mutable_state += 1;
+        break :blk1 @as(f64, 10.0);
+    } != blk2: {
+        try expect(mutable_state == 2);
+        break :blk2 @as(?f64, 5.0);
+    };
+}
+
+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 "unwrap function call with optional pointer return value" {
+    const S = struct {
+        fn entry() !void {
+            try expect(foo().?.* == 1234);
+            try expect(bar() == null);
+        }
+        const global: i32 = 1234;
+        fn foo() ?*const i32 {
+            return &global;
+        }
+        fn bar() ?*i32 {
+            return null;
+        }
+    };
+    try S.entry();
+    comptime try S.entry();
+}
+
+test "nested orelse" {
+    const S = struct {
+        fn entry() !void {
+            try expect(func() == null);
+        }
+        fn maybe() ?Foo {
+            return null;
+        }
+        fn func() ?Foo {
+            const x = maybe() orelse
+                maybe() orelse
+                return null;
+            _ = x;
+            unreachable;
+        }
+        const Foo = struct {
+            field: i32,
+        };
+    };
+    try S.entry();
+    comptime try 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);
+}
+
+test "assigning to an unwrapped optional field in an inline loop" {
+    comptime var maybe_pos_arg: ?comptime_int = null;
+    inline for ("ab") |x| {
+        _ = x;
+        maybe_pos_arg = 0;
+        if (maybe_pos_arg.? != 0) {
+            @compileError("bad");
+        }
+        maybe_pos_arg.? = 10;
+    }
+}
+
+test "coerce an anon struct literal to optional struct" {
+    const S = struct {
+        const Struct = struct {
+            field: u32,
+        };
+        fn doTheTest() !void {
+            var maybe_dims: ?Struct = null;
+            maybe_dims = .{ .field = 1 };
+            try expect(maybe_dims.?.field == 1);
+        }
+    };
+    try S.doTheTest();
+    comptime try S.doTheTest();
+}
+
+test "optional with void type" {
+    const Foo = struct {
+        x: ?void,
+    };
+    var x = Foo{ .x = null };
+    try expect(x.x == null);
+}
+
+test "0-bit child type coerced to optional return ptr result location" {
+    const S = struct {
+        fn doTheTest() !void {
+            var y = Foo{};
+            var z = y.thing();
+            try expect(z != null);
+        }
+
+        const Foo = struct {
+            pub const Bar = struct {
+                field: *Foo,
+            };
+
+            pub fn thing(self: *Foo) ?Bar {
+                return Bar{ .field = self };
+            }
+        };
+    };
+    try S.doTheTest();
+    comptime try S.doTheTest();
+}
+
+test "0-bit child type coerced to optional" {
+    const S = struct {
+        fn doTheTest() !void {
+            var it: Foo = .{
+                .list = undefined,
+            };
+            try expect(it.foo() != null);
+        }
+
+        const Empty = struct {};
+        const Foo = struct {
+            list: [10]Empty,
+
+            fn foo(self: *Foo) ?*Empty {
+                const data = &self.list[0];
+                return data;
+            }
+        };
+    };
+    try S.doTheTest();
+    comptime try S.doTheTest();
+}
+
+test "array of optional unaligned types" {
+    const Enum = enum { one, two, three };
+
+    const SomeUnion = union(enum) {
+        Num: Enum,
+        Other: u32,
+    };
+
+    const values = [_]?SomeUnion{
+        SomeUnion{ .Num = .one },
+        SomeUnion{ .Num = .two },
+        SomeUnion{ .Num = .three },
+        SomeUnion{ .Num = .one },
+        SomeUnion{ .Num = .two },
+        SomeUnion{ .Num = .three },
+    };
+
+    // The index must be a runtime value
+    var i: usize = 0;
+    try expectEqual(Enum.one, values[i].?.Num);
+    i += 1;
+    try expectEqual(Enum.two, values[i].?.Num);
+    i += 1;
+    try expectEqual(Enum.three, values[i].?.Num);
+    i += 1;
+    try expectEqual(Enum.one, values[i].?.Num);
+    i += 1;
+    try expectEqual(Enum.two, values[i].?.Num);
+    i += 1;
+    try expectEqual(Enum.three, values[i].?.Num);
+}
+
+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);
+}
test/behavior/slice_stage1.zig
@@ -20,6 +20,47 @@ test "slicing" {
     if (slice_rest.len != 10) unreachable;
 }
 
+test "slicing zero length array" {
+    const s1 = ""[0..];
+    const s2 = ([_]u32{})[0..];
+    try expect(s1.len == 0);
+    try expect(s2.len == 0);
+    try expect(mem.eql(u8, s1, ""));
+    try expect(mem.eql(u32, s2, &[_]u32{}));
+}
+
+test "slice string literal has correct type" {
+    comptime {
+        try expect(@TypeOf("aoeu"[0..]) == *const [4:0]u8);
+        const array = [_]i32{ 1, 2, 3, 4 };
+        try expect(@TypeOf(array[0..]) == *const [4]i32);
+    }
+    var runtime_zero: usize = 0;
+    comptime try expect(@TypeOf("aoeu"[runtime_zero..]) == [:0]const u8);
+    const array = [_]i32{ 1, 2, 3, 4 };
+    comptime try expect(@TypeOf(array[runtime_zero..]) == []const i32);
+}
+
+test "generic malloc free" {
+    const a = memAlloc(u8, 10) catch unreachable;
+    memFree(u8, a);
+}
+var some_mem: [100]u8 = undefined;
+fn memAlloc(comptime T: type, n: usize) anyerror![]T {
+    return @ptrCast([*]T, &some_mem[0])[0..n];
+}
+fn memFree(comptime T: type, memory: []T) void {
+    _ = memory;
+}
+
+test "result location zero sized array inside struct field implicit cast to slice" {
+    const E = struct {
+        entries: []u32,
+    };
+    var foo = E{ .entries = &[_]u32{} };
+    try expect(foo.entries.len == 0);
+}
+
 const x = @intToPtr([*]i32, 0x1000)[0..0x500];
 const y = x[0x100..];
 test "compile time slice of pointer to hard coded address" {
test/behavior.zig
@@ -25,6 +25,7 @@ test {
     _ = @import("behavior/if.zig");
     _ = @import("behavior/math.zig");
     _ = @import("behavior/member_func.zig");
+    _ = @import("behavior/optional.zig");
     _ = @import("behavior/pointers.zig");
     _ = @import("behavior/slice.zig");
     _ = @import("behavior/sizeof_and_typeof.zig");
@@ -135,7 +136,7 @@ test {
         _ = @import("behavior/muladd.zig");
         _ = @import("behavior/namespace_depends_on_compile_var.zig");
         _ = @import("behavior/null.zig");
-        _ = @import("behavior/optional.zig");
+        _ = @import("behavior/optional_stage1.zig");
         _ = @import("behavior/pointers_stage1.zig");
         _ = @import("behavior/popcount.zig");
         _ = @import("behavior/ptrcast.zig");