Skip to content

Known limitations of branch coverage instrumentation #124118

Open
@Zalathar

Description

@Zalathar

Branch coverage is known to support these branching language constructs:

  • if and while
    • Includes if let and let-chains
    • Treats nested || and && as separate branches
    • while desugars to if before MIR building, so we support it as a consequence of supporting if
  • Standalone || and && expressions
  • 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
    • But their presence makes it more complicated to instrument match arms, as described below

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
    • 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
  • 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
  • .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
  • 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:

(Rewritten on 2024-07-11; see edit history for the old text.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-code-coverageArea: Source-based code coverage (-Cinstrument-coverage)T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions