langref: make example more interesting.

As written, I think langref's example is actually a poor reason to use
`inline`.

If you have

     if (foo(1200, 34) != 1234) {
         @compileError("bad");
     }

and you want to make sure that the call is executed at compile time, the
right way to fix it is to add comptime

     if (comptime foo(1200, 34) != 1234) {
         @compileError("bad");
     }

and not to make the function `inline`. I _think_ that inlining functions
just to avoid `comptime` at a call-site is an anti-pattern. When the
reader sees `foo(123)` at the call-site, they _expect_ this to be a
runtime call, as that's the normal rule in Zig.

Inline is still necessary when you can't make the _whole_ call
`comptime`, because it has some runtime effects, but you still want
comptime-known result.

A good example here is

    inline fn findImportPkgHashOrFatal(b: *Build, comptime asking_build_zig: type, comptime dep_name: []const u8) []const u8 {

from Build.zig, where the `b` argument is runtime, and is used for
side-effects, but where the result is comptime.

I don't know of a good small example to demonstrate the subtelty here,
so I went ahead with just adding a runtime print to `foo`. Hopefully
it'll be enough for motivated reader to appreciate the subtelty!
This commit is contained in:
Alex Kladov 2025-07-14 16:12:55 +01:00
parent f43f89a705
commit d045eb7a4a

View File

@ -1,3 +1,5 @@
const std = @import("std");
test "inline function call" {
if (foo(1200, 34) != 1234) {
@compileError("bad");
@ -5,6 +7,7 @@ test "inline function call" {
}
inline fn foo(a: i32, b: i32) i32 {
std.debug.print("runtime a = {} b = {}", .{ a, b });
return a + b;
}