Skip to content

Conversation

@rw1nkler
Copy link
Contributor

@rw1nkler rw1nkler commented Oct 31, 2025

This PR adds support for the constexpr if expression.

Information about the const modifier is stored in the Conditional class and used later during type checking. For constexpr if, separate type variables are assigned to each branch of the condition. At this stage, the result is not directly bound to them. During the TypeInfo generation, the constexpr condition is evaluated, and one branch of the if is selected. Its type is unified, and the entire if is annotated with that type. The bytecode emitter and IR converter have been updated to inline the selected branch, skipping the unchosen one.

Proper tests for this feature are still needed and will be added soon.

One issue not yet handled correctly in this PR is the conditional spawning of procs, for which an example has been added that shows the problem. Currently, all spawns affect the type, which should not happen as only the selected branch of constexpr if should be considered. One possible approach is to enable constexpr evaluator in the PopulateInferenceTableVisitor and skip traversing the branch that was not taken. However, the PopulateInferenceTableVisitor does not have access to the parametric environment, and the condition relying on the parametrics seems to be the most imprtant use-case for using constexpr if when spawning procs.

// Later during the generation of TypeInfo, after resolving parametrics,
// and evaluating the test condition, we force the type of the selected
// if branch on the conditional node.
XLS_RETURN_IF_ERROR(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this would be more in-model if we would define a new type of internal type annotation, like ConstConditionalTypeAnnotation, and set an instance of that on the Conditional node in the const case. The ConstConditionalTypeAnnotation could have the const test Expr as a member, and a TVTA for each possible branch.

TypeAnnotationResolver would then perform the resolution logic that you currently have inside GenerateTypeInfo (in a manner similar to MemberTypeAnnotation, ElementTypeAnnotation, etc.).

Aside from that this all looks reasonable.

table_.SetTypeVariable(node->consequent(), type_variable));
XLS_RETURN_IF_ERROR(
table_.SetTypeVariable(ToAstNode(node->alternate()), type_variable));
if (!node->IsConst()) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually we prefer to use positive conditions in a C++ if statement, even if it leads to the less common branch being first (so flip the 2 branches here).

Signed-off-by: Robert Winkler <[email protected]>
@rw1nkler rw1nkler force-pushed the 80074-const-if branch 2 times, most recently from d236527 to 43ce9af Compare November 18, 2025 14:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants