Commit f47f6d766e

mlugg <mlugg@mlugg.co.uk>
2024-08-24 17:51:05
behavior,cases: add `@branchHint` test coverage
1 parent 6808ce2
Changed files (2)
test
behavior
cases
test/behavior/basic.zig
@@ -107,13 +107,90 @@ test "non const ptr to aliased type" {
     try expect(?*int == ?*i32);
 }
 
-test "cold function" {
-    thisIsAColdFn();
-    comptime thisIsAColdFn();
+test "function branch hints" {
+    const S = struct {
+        fn none() void {
+            @branchHint(.none);
+        }
+        fn likely() void {
+            @branchHint(.likely);
+        }
+        fn unlikely() void {
+            @branchHint(.unlikely);
+        }
+        fn cold() void {
+            @branchHint(.cold);
+        }
+        fn unpredictable() void {
+            @branchHint(.unpredictable);
+        }
+    };
+    S.none();
+    S.likely();
+    S.unlikely();
+    S.cold();
+    S.unpredictable();
+    comptime S.none();
+    comptime S.likely();
+    comptime S.unlikely();
+    comptime S.cold();
+    comptime S.unpredictable();
+}
+
+test "if branch hints" {
+    var t: bool = undefined;
+    t = true;
+    if (t) {
+        @branchHint(.likely);
+    } else {
+        @branchHint(.cold);
+    }
 }
 
-fn thisIsAColdFn() void {
-    @branchHint(.cold);
+test "switch branch hints" {
+    var t: bool = undefined;
+    t = true;
+    switch (t) {
+        true => {
+            @branchHint(.likely);
+        },
+        false => {
+            @branchHint(.cold);
+        },
+    }
+}
+
+test "orelse branch hints" {
+    var x: ?u32 = undefined;
+    x = 123;
+    const val = x orelse val: {
+        @branchHint(.cold);
+        break :val 456;
+    };
+    try expect(val == 123);
+}
+
+test "catch branch hints" {
+    var x: error{Bad}!u32 = undefined;
+    x = 123;
+    const val = x catch val: {
+        @branchHint(.cold);
+        break :val 456;
+    };
+    try expect(val == 123);
+}
+
+test "and/or branch hints" {
+    var t: bool = undefined;
+    t = true;
+    try expect(t or b: {
+        @branchHint(.unlikely);
+        break :b false;
+    });
+    try expect(t and b: {
+        @branchHint(.likely);
+        break :b true;
+    });
 }
 
 test "unicode escape in character literal" {
test/cases/compile_errors/invalid_branch_hint.zig
@@ -0,0 +1,41 @@
+const globl = g: {
+    @branchHint(.none);
+    break :g {};
+};
+
+comptime {
+    @branchHint(.none);
+}
+
+test {
+    @branchHint(.none);
+}
+
+export fn foo() void {
+    {
+        @branchHint(.none);
+    }
+}
+
+export fn bar() void {
+    _ = (b: {
+        @branchHint(.none);
+        break :b true;
+    }) or true;
+}
+
+export fn qux() void {
+    (b: {
+        @branchHint(.none);
+        break :b @as(?void, {});
+    }) orelse unreachable;
+}
+
+// error
+//
+// :2:5: error: '@branchHint' outside function scope
+// :7:5: error: '@branchHint' outside function scope
+// :11:5: error: '@branchHint' must appear as the first statement in a function or conditional branch
+// :16:9: error: '@branchHint' must appear as the first statement in a function or conditional branch
+// :22:9: error: '@branchHint' must appear as the first statement in a function or conditional branch
+// :29:9: error: '@branchHint' must appear as the first statement in a function or conditional branch