stage2: optional comparison and 0-bit payloads

* Sema: implement peer type resolution for optionals and null.
 * Rename `Module.optionalType` to `Type.optional`.
 * LLVM backend: re-use anonymous values. This is especially useful when
   isByRef()=true because it means re-using the same generated LLVM globals.
 * LLVM backend: rework the implementation of is_null and is_non_null
   AIR instructions. Generate slightly better LLVM code, and also fix
   the behavior for optionals whose payload type is 0-bit.
 * LLVM backend: improve `cmp` AIR instruction lowering to support
   pointer-like optionals.
 * `Value`: implement support for equality-checking optionals.
This commit is contained in:
Andrew Kelley
2021-10-15 18:37:09 -07:00
parent 186126c2a4
commit 682cdeceaa
7 changed files with 171 additions and 96 deletions

View File

@@ -44,3 +44,32 @@ test "optional pointer to size zero struct" {
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);
}