Skip to content
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

Control flow analysis pass for macro compiler #41

Closed
plaidfinch opened this issue Feb 23, 2021 · 0 comments
Closed

Control flow analysis pass for macro compiler #41

plaidfinch opened this issue Feb 23, 2021 · 0 comments
Assignees
Labels

Comments

@plaidfinch
Copy link
Contributor

Session! macro invocations that contain "dead code"—that is, surface syntax which would be compiled to nothing, can be written and parsed, but we should not allow them, to avoid confusion. For instance, consider the type:

type NeverSends0 = Session! {
    loop {
        recv ();
        continue;
        send ();
};

The macro compiler must translate this to the session type Loop<Recv<(), Continue>>, but this is confusing to the end user because while they wrote send (), it never occurs in the type. Such dead code should be marked by the macro. Unfortunately, we can't generate a warning (as Rust does in value-level dead code), so instead we should generate an error.

Naively, we might imagine we could avoid such situations by scanning all Blocks in the IR AST to see whether they contain continue or break statements that are not at their end, but this is not sufficient. Consider the following:

type NeverSends1 = Session! {
    loop {
        recv ();
        offer {
            _0 => continue,
            _1 => break,
        };
        send ();
};

This would compile to Loop<Recv<(), Offer<(Continue, Done)>>>. The naive analysis above would not identify this case because neither continue nor break occur in the middle of a block in this macro invocation. What is needed is true control flow analysis.

The analysis must run before the elimination of Break nodes, because that pass itself slices out sections of dead code and makes them unreachable. Additionally, if any errors are discovered in this pass, we should not proceed to eliminate Break nodes, as this would remove the very error nodes inserted by this pass! We need to produce to the user both the errors generated during this pass and all others currently embedded in the AST.

A related control flow analysis which could be bundled in this pass: session types are only impl Session if all their loops are productive: that is, there is at least one real action (something other than Loop) between the loop head and the Continue that points to it. If this is not the case, a rather obscure constraint solver overflow error occurs. We could detect this error during this pass, and report it, improving diagnostics for users.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants