-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Unexpected type dependency loop when declaring a function pointer to a function that returns its own type. #18664
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Duplicate #12325 likely |
I get this running it
|
With the latest master binaries produced on 2024-01-25, zig version "0.12.0-dev.2341+92211135f" I am still getting "dependency loop detected". |
Related dependency loop issues #16932 and #131 smaller test case: const StateFn = *const fn () ?StateFn;
fn done() ?StateFn {
return null;
}
test {
_ = done();
} zig 0.12.0-dev.2928+6fddc9cd3 output:
|
I should note you can work around this by wrapping this data in a struct: const State = struct {
evalFn: *const fn () ?State,
}; The error here happens because we only have lazy resolution (which permits recursive definitions) for structs, unions, enums, and opaques. It's not exactly a duplicate, but is heavily related to #12325. |
Thank you very much @mlugg for the workaround |
Thank you @mlugg for the prompt workaround to #22543 I had a question about that, but you closed it, so I'll ask here. I changed your workaround to: const std = @import("std");
const execute = struct {
const ThreadedFn = struct {
f: *const fn (
process: *Process,
context: *Context,
) void,
};
};
const Process = struct {
debugFn: ?execute.ThreadedFn,
};
const Context = struct {
npc: execute.ThreadedFn,
};
test "die" {
_ = Process{
.debugFn = null,
};
} and that seems to work. Is there a footgun hiding in that solution? (I worry because you said 'This is a little awkward because you can't just have a ?ThreadedFn' but it seems to be OK.) |
The issue there is that the optional is no longer represented as a null pointer, but rather with an extra tag stored separately. So, you couldn't e.g. pass that to a C API which expected a plain old nullable pointer. If that isn't a problem for you, then your code works fine (although bear in mind that it uses a bit more memory than an optional pointer). |
Right, because then it's an optional struct (even though it's one word), not an optional function pointer. and doing Simplest for my case is to not make it optional, but point to a function that doesn't do anything. Thanks, again. |
Zig Version
0.11.0, 0.12.0-dev.2327+b0c8a3f31
Steps to Reproduce and Observed Behavior
Example program:
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=110The text was updated successfully, but these errors were encountered: