From f47f6d766e236c75af3c26cc9dec07a46725dba0 Mon Sep 17 00:00:00 2001 From: mlugg Date: Sat, 24 Aug 2024 16:51:05 +0100 Subject: [PATCH] behavior,cases: add `@branchHint` test coverage --- test/behavior/basic.zig | 87 +++++++++++++++++-- .../compile_errors/invalid_branch_hint.zig | 41 +++++++++ 2 files changed, 123 insertions(+), 5 deletions(-) create mode 100644 test/cases/compile_errors/invalid_branch_hint.zig diff --git a/test/behavior/basic.zig b/test/behavior/basic.zig index b96ab2fb06..4e5d0d55ab 100644 --- a/test/behavior/basic.zig +++ b/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(); } -fn thisIsAColdFn() void { - @branchHint(.cold); +test "if branch hints" { + var t: bool = undefined; + t = true; + if (t) { + @branchHint(.likely); + } else { + @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" { diff --git a/test/cases/compile_errors/invalid_branch_hint.zig b/test/cases/compile_errors/invalid_branch_hint.zig new file mode 100644 index 0000000000..1ceb8a686e --- /dev/null +++ b/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