-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Recursion detection is over aggressive #10967
Comments
I didn't try compiling the code, but here's a suggested solution.
I think this is a mismatch in expectations. Zig currently aims for making all recursion explicit, to enable calculating a static bound for all stack growth over the stack's lifetime. See issues #157 and #1006. This would limit programs from "naturally" using recursion. This in itself has no connection to So, the actual issue is the fact that you're calling recursive code (in particular, it seems Then the only other solution (for the forseeable future) would be to:
This should also force you to handle allocation failure of new stack frames, which the code (from what I can tell) currently doesn't consider. |
The zig-yaml library was apparently not built to support evented io mode. You will need to open an issue with it instead, or disable evented io. Recursion into a function which has no suspends is allowed. But remember that calling an async function counts as a suspend. Evented io turns many core io functions into suspend points through this mechanism. |
@rohlem That makes sense. Would that mean in the future calls to extern c functions and calls to function pointers would require setting the stack size in some way, or allocating a stacklet? I'll mark this as closed. |
@bpeake13 The way I remember it, function pointer types would need to be enhanced with the stack size the caller must provide, and external functions would be similarly be annotated the stack size they require. Again, there should be some way to provide a manually-allocated stack. However, to clarify, please also consider the comment from @SpexGuy above; they're an active developer on the project (unlike me), so probably more knowledgeable. While our comments seem to contradict, I'm talking based on what I remember the discussion being when I heard it mentioned 1-2 years ago. I believe that, as they state it, currently recursion may still be allowed, and your current issue might be resolved by using blocking io-mode (defining The Zig compiler is currently being rewritten (named |
Zig Version
0.9.1
Steps to Reproduce
Unsure if this is a bug or a feature request, it feels like a bug because this behavior does work with extern c functions, and other functions that could potentially be recursive, but cannot suspend.
Probably can be produced with other code, i discovered it while using this library:
https://github.com/kubkon/zig-yaml
Compile the following code using said library:
The code fails to compile, stating that yamlTestFunc references a recursive async function. This code also fails with the same errors even if we we call with no_async, reference through a function pointer, or attempt to start a new thread that calls that function.
Example:
This will fail, stating a recursive error, even though the function is call from another thread.
Expected Behavior
These scenarios should not cause compiler errors. In some scenarios we can promise that the function does not need to be async, as it has no suspends, so recursion should be acceptable. This behavior would mirror that of calling an extern c from an async block, which is allowed.
The scenarios where the function is not actually called from the async frame should not result in errors, as it does not break any async recursion rules.
Actual Behavior
Any function that is detected as being recursive, that is referenced from an async frame, no matter if it is actually called or used, results in a compiler error.
The text was updated successfully, but these errors were encountered: