Skip to content

Can't call inline function that returns comptime-known comptime-only type at runtime #18987

@castholm

Description

@castholm

Zig Version

0.12.0-dev.2711+f995c1b08

Steps to Reproduce and Observed Behavior

Extracted from #18808 (comment)

However... when I tried this example below I was actually surprised:

const std = @import("std");

extern fn side_effect(*i32) void;

inline fn example(runtime_known: *i32, comptime x: bool) type {
    if (x) {
        return f32;
    } else {
        side_effect(runtime_known);
    }
}

test "pass runtime param, receive comptime value" {
    const ptr = try std.testing.allocator.create(i32);
    defer std.testing.allocator.destroy(ptr);

    const T = example(ptr, true);
    try std.testing.expect(T == f32);
}
test.zig:17:23: error: unable to resolve comptime value
    const T = example(ptr, true);
                      ^~~
test.zig:17:23: note: argument to function being called at comptime must be comptime-known
test.zig:5:58: note: expression is evaluated at comptime because the function returns a comptime-only type 'type'
inline fn example(runtime_known: *i32, comptime x: bool) type {
                                                         ^~~~
test.zig:5:58: note: types are not available at runtime
inline fn example(runtime_known: *i32, comptime x: bool) type {
                                                         ^~~~

The problem here is that the return type forces the function call to be comptime, when we actually just wanted it to be inline. I will open a bug report for this.

I couldn't find a bug report.

Another quick test that should succeed:

const std = @import("std");

test "inline function with comptime-known comptime-only return type called at runtime" {
    const S = struct {
        inline fn foo(x: *i32, y: *const i32) type {
            x.* = y.*;
            return f32;
        }
    };
    var a: i32 = 0;
    const b: i32 = 111;
    const T = S.foo(&a, &b);
    try std.testing.expectEqual(111, a);
    try std.testing.expectEqual(f32, T);
}

Expected Behavior

All tests pass.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behaviorfrontendTokenization, parsing, AstGen, Sema, and Liveness.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions