infer: don't trust a transiently void call when accepting 'return void_expr' - #3894
Merged
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR hardens return-type inference around the recently-added support for return <void_expr> by preventing transient “void-typed” call expressions (e.g., during constant-expression folding / call transforms) from irreversibly pinning a bare auto result type to void or triggering early lowering.
Changes:
- Adds
InferTypes::isVoidReturnValueSettledand uses it to gate both (a) acceptingreturn void_exprfor bare-autoresult inference and (b) loweringreturn void_exprinto{ void_expr; return; }. - Updates the
ExprReturninference path to defer withnot_resolved_yet_expression_typewhen a void-typed call’s callee is not yet settled/bound. - Adds a regression test covering a
[generic, constant_expression]scenario where a call is transiently void until folding finalizes its type.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| tests/language/return_void_expression.das | Adds regression coverage for transiently-void generic calls not poisoning bare-auto return inference. |
| src/ast/ast_infer_type.cpp | Gates the return void_expr lowering on the new “void return value settled” predicate. |
| src/ast/ast_infer_type_helper.cpp | Introduces isVoidReturnValueSettled and uses it to defer inference when a void-typed call is transient/unsettled. |
| include/daScript/ast/ast_infer_type.h | Declares the new InferTypes::isVoidReturnValueSettled helper. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…d_expr' PR GaijinEntertainment#3861 accepts 'return void_expr' and resolves a bare auto result to void through the regular generic-infer machinery. That commit is irreversible, and the subexpression's void type is not always final: a [generic] instance still pending [constant_expression] folding is an empty void function for a pass or two (its body sits under 'static_if !typeinfo is_argument(...)'), and the transform then swaps the call for a clone that briefly carries the stale void type with no function bound. Locking the caller's auto result to void off that state, or lowering the return to { expr; return; }, poisons the function for good; every pre-GaijinEntertainment#3861 compiler simply erred on that pass and retried. Add InferTypes::isVoidReturnValueSettled: a void-typed ExprCallFunc only counts once its callee settled (builtin, fully inferred, or from an already compiled module; a call with no function bound never does). Until then the return defers with not-resolved-yet, same as any other unresolved subexpression. Non-call void subexpressions (block invokes, etc.) are unaffected. Adds a regression test: a bare-auto function returning calls to a [generic, constant_expression] function must infer the folded instance's type, not void.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR #3861 accepts 'return void_expr' and resolves a bare auto result to void through the regular generic-infer machinery. That commit is irreversible, and the subexpression's void type is not always final: a [generic] instance still pending [constant_expression] folding is an empty void function for a pass or two (its body sits under 'static_if !typeinfo is_argument(...)'), and the transform then swaps the call for a clone that briefly carries the stale void type with no function bound. Locking the caller's auto result to void off that state, or lowering the return to { expr; return; }, poisons the function for good; every pre-#3861 compiler simply erred on that pass and retried.
Add InferTypes::isVoidReturnValueSettled: a void-typed ExprCallFunc only counts once its callee settled (builtin, fully inferred, or from an already compiled module; a call with no function bound never does). Until then the return defers with not-resolved-yet, same as any other unresolved subexpression. Non-call void subexpressions (block invokes, etc.) are unaffected.
Adds a regression test: a bare-auto function returning calls to a [generic, constant_expression] function must infer the folded instance's type, not void.