Skip to content

Always explicitly reference current_block values #1522

@randomPoison

Description

@randomPoison

Today, when we generate match current_block {} expressions, we pick one of the arms of the match to be the _ case in order satisfy match's exhaustiveness requirement. This makes reasoning about current_block control flow difficult because you can't search for the value of a current_block constant to see where it's used.

Instead, we should have an arm that explicitly references the current_block value, and then a _ => unreachable!() arm to satisfy exhaustiveness.

Details

Today, when we emit current_block, we generate code that looks a bit like this:

let mut current_block;
if cond {
    current_block = 123456789;
} else {
    current_block = 987654321;
}
match current_block {
    123456789 => { ... }
    _ => { ... }
}

If I want to figure out what code each current_block value leads to (in practice setting current_block may happen very far away from where we match on it), I can search the code for 123456789 and see both where it's set and where it's used. But the other label 987654321 doesn't show up in the match because it's instead covered by the _ case.

We do this to satisfy exhaustiveness: current_block is just an integer, so if we did

match current_block {
    123456789 => { ... }
    987654321 => { ... }
}

The compiler would complain that our match isn't exhaustive. Since we control all the possible values that current_block will have, it's valid for us to arbitrarily pick one of these arms and make it the _ case. However, as noted above, this harms readability and makes it harder to reason about how current_block is being used.

Instead we should do this

match current_block {
    123456789 => { ... }
    987654321 => { ... }
    _ => unreachable!(),
}

This would ensure that you can always see all the places where a current_block value is used, which would make reasoning about current_block control flow easier.

Metadata

Metadata

Assignees

No one assigned

    Labels

    control flowenhancementNew feature or requestreadabilityGenerated code is hard to read and can be simplified

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions