Skip to content

Unexpected type dependency loop when declaring a function pointer to a function that returns its own type. #18664

Open
@dimdin

Description

@dimdin

Zig Version

0.11.0, 0.12.0-dev.2327+b0c8a3f31

Steps to Reproduce and Observed Behavior

state.zig:6:1: error: dependency loop detected
const StateFn = *const fn (In, *Out) ?StateFn;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Example program:

const std = @import("std");

const In = struct {};
const Out = struct {};

const StateFn = *const fn (In, *Out) ?StateFn;

// trampoline
fn run(in: In, out: *Out, initial_state: StateFn) void {
    var current_state: StateFn = initial_state;
    while (current_state(in, out)) |state| {
        current_state = state;
    }
}

fn firstState(in: In, out: *Out) ?StateFn {
    _ = in;
    _ = out;
    std.log.debug("in first state", .{});
    return lastState;
}

fn lastState(in: In, out: *Out) ?StateFn {
    _ = in;
    _ = out;
    std.log.debug("in last state", .{});
    return null;
}

test "run state machine" {
    var out: Out = undefined;
    const in: In = undefined;
    run(in, &out, firstState);
}

Expected Behavior

Expecting zig compiler to accept the function pointer declaration of a function that returns itself.
Such declarations are useful in lexer/scanner trampolines.

Example golang code: https://cs.opensource.google/go/go/+/master:src/text/template/parse/lex.go;l=110

type stateFn func(*lexer) stateFn

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behavior

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions