Open
Description
Branch coverage is known to support these branching language constructs:
if
andwhile
- Includes
if let
and let-chains - Treats nested
||
and&&
as separate branches while
desugars toif
before MIR building, so we support it as a consequence of supportingif
- Includes
- Standalone
||
and&&
expressions- Nested
||
and&&
are treated as separate branches - The final operand is not a branch, but can be optionally treated as one via coverage: Optionally instrument the RHS of lazy logical operators #125756
- Nested
let
-else
statements- Match arm guards
- These also desugar to
if
expressions before MIR building- This also means that we naturally support
if let
guards
- This also means that we naturally support
- But their presence makes it more complicated to instrument match arms, as described below
- These also desugar to
Branch coverage is known to not yet support these branching language constructs:
- Individual arms and or-patterns in
match
expressions- We need to be sure to support (or gracefully not support) all four combinations of:
- Arms with/without guards
- The guards themselves are already supported (as indicated above), but their presence also complicates how we instrument the enclosing match arm, and other match arms in the same match
- Note that the combination of guards and or-patterns results in particularly complex control-flow, because if a guard fails then we keep searching for other or-pattern matches in the same arm
- Arms with/without or-patterns, including arbitrary nesting
- Arms with/without guards
- coverage: Treat each match arm as a "branch" for branch coverage #124154
- This draft does not support or-patterns, and might not be able to support them without substantial changes (requiring a different approach)
- This draft uses complex counter expressions to work around not being able to instrument all the appropriate points in the control-flow graph directly; this ties back into concerns about or-patterns
- We need to be sure to support (or gracefully not support) all four combinations of:
- The try
?
operator (which conditionally returns)- This is desugared to a
match
expression, so once we support those, supporting?
should mostly be a matter of expansion-span bookkeeping
- This is desugared to a
-
.await
expressions (which implicitly “return” when the enclosing future is dropped)- This can probably be excluded from any MVP of branch coverage, unless it turns out to be unexpectedly easy after supporting
?
- But some users will presumably want this in the long run
- This can probably be excluded from any MVP of branch coverage, unless it turns out to be unexpectedly easy after supporting
- Any of the above branching constructs that are introduced by macro expansion
- The current implementation discards any branch span that isn't “directly visible” in the function body
Relevant PR links:
- coverage: Initial support for branch coverage instrumentation #122322
- coverage: Branch coverage support for let-else and if-let #124223
- coverage: Treat each match arm as a "branch" for branch coverage #124154
(Rewritten on 2024-07-11; see edit history for the old text.)