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

Support mcdc analysis for pattern matching #124278

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

ZhuUx
Copy link
Contributor

@ZhuUx ZhuUx commented Apr 23, 2024

To finish the second task at #124144.

Changes

  • Implement branch coverage for pattern matching specific to mcdc. As suggested at #124217, mcdc would better implement its own branch coverage methods for pattern match.
    That means, coverage-options=mcdc may give different branch coverage results of pattern matching with coverage-options=branch temporarily.
  • Generate decision mappings for all refutable patterns in match.

Note. The results might be a bit counter intuitive due to reorder as this comment introduces.

@rustbot
Copy link
Collaborator

rustbot commented Apr 23, 2024

r? @wesleywiser

rustbot has assigned @wesleywiser.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Apr 23, 2024
@ZhuUx
Copy link
Contributor Author

ZhuUx commented Apr 23, 2024

For now there are still some work need to do and some code is not well optimized to reduce work in merging #124255 .
r? @ghost
@rustbot label +A-code-coverage
@rustbot author

@rustbot
Copy link
Collaborator

rustbot commented Apr 23, 2024

Failed to set assignee to ghost: invalid assignee

Note: Only org members with at least the repository "read" role, users with write permissions, or people who have commented on the PR may be assigned.

@rustbot rustbot added A-code-coverage Area: Source-based code coverage (-Cinstrument-coverage) S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 23, 2024
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@ZhuUx ZhuUx force-pushed the pattern-match branch 2 times, most recently from 39732bf to 0255b0b Compare April 24, 2024 02:39
@Lambdaris
Copy link

Lambdaris commented Apr 24, 2024

Determining decision of pattern matching is more tricky than expected. I should write it down here in case someone feels confused about it.
I'm not sure if rustc promises anything about the order of checked pattern (probably not), so the description here should be only taken as a specific way determined by the implementation of compiler when this pr is drafting.

We call patterns like ( A | B, C (X | Y) ) as candidates, each candidate has match pairs which indicates sub patterns and also has their "sub pairs". For example, candidate for ( A | B, C (X | Y) ) has match pairs for A | B (let's call it M1) and C (X | Y) (M2) separately. Also M1 has sub pairs for A and B and M2 has sub pair X | Y.

The first rule is that candidate is constructed where all match pairs representing | pattern (directly) are moved to last
This is done at simplify_match_pairs.
For the example compiler checks C first because A | B is or pattern while C is not directly (though it has an or sub pattern).

The second rule is the first pair will be removed and compiler will insert its sub pairs into the candidate's match pairs if it is "full matched"
This is done at sort_candidate.
So when compiler checks C first, it removes it and takes match pair representing X | Y as the candidate's last match pair. If the sub pattern in C were not |, it would be inserted at front of all or patterns as the code suggests.

Thus in all, the evaluate order of if let ( A | B, C (X | Y) ) = val is:

  1. Check whether val.1 is C,
  2. Check whether val.0 is A | B,
  3. Check whether val.1.0 is X | Y.

While the order of if let (A | B, C(X)) = val is:

  1. Check whether val.1 is C,
  2. Check whether val.1.0 is X,
  3. Check whether val.0 is A | B.

And the order of if let (A(Z), C) = val is:

  1. Check whether val.0 is A,
  2. Check whether val.0.0 is Z,
  3. Check whether val.1 is C.

A more mischievous example is if let (A | B, C (X | Y, Z), D) = val, its control flow would be like:

  1. Check whether val.1 is C,
  2. Check whether val.2 is D,
  3. Check whether val.1.1 is Z,
  4. Check whether val.0 is A | B,
  5. Check whether val.1.0 is X | Y.

Hopefully the decision structure were not taken as mischief by users.

@ZhuUx ZhuUx changed the title Support mcdc analysis for pattern match Support mcdc analysis for pattern matching Apr 24, 2024
@rust-log-analyzer

This comment has been minimized.

@ZhuUx
Copy link
Contributor Author

ZhuUx commented Apr 28, 2024

I have pushed an impractical commit to show design for constructing decisions and mcdc branches of pattern matching.
Mostly is in MCDCDecisionBuilder. I'd like to finish it after merging #124255 and #124399 because the way to inject block marker should be changed.
But still any comments about it are welcomed.

@rust-log-analyzer

This comment has been minimized.

@bors
Copy link
Contributor

bors commented Apr 29, 2024

☔ The latest upstream changes (presumably #124255) made this pull request unmergeable. Please resolve the merge conflicts.

bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 30, 2024
Split mcdc code to a sub module of coverageinfo

A further work from rust-lang#124217 . I have made relatively large changes when working on rust-lang#124278 so that it would better split them from `coverageinfo.rs` to avoid potential troubling merge work with improved branch coverage by `@Zalathar` .

Besides `BlockMarkerGenerator` is added to avoid ownership problems (mostly needed for following change of rust-lang#124278 )

All code changes are done in [a37d737a](rust-lang@a3d737a) while the second commit just renames the file.

cc `@RenjiSann` `@Zalathar`
This will impact your current work.
@ZhuUx
Copy link
Contributor Author

ZhuUx commented May 10, 2024

Implementation for if-let has been drafted. Due to llvm does not support nested decisions yet tests for let-chains are not added. I should try to reduce coverage expressions and investigate if it works for matching guards later.

@bors
Copy link
Contributor

bors commented May 10, 2024

☔ The latest upstream changes (presumably #124972) made this pull request unmergeable. Please resolve the merge conflicts.

@rust-log-analyzer

This comment has been minimized.

@bors
Copy link
Contributor

bors commented Jul 12, 2024

☔ The latest upstream changes (presumably #127635) made this pull request unmergeable. Please resolve the merge conflicts.

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Jul 15, 2024
coverage: Restrict `ExpressionUsed` simplification to `Code` mappings

In the future, branch and MC/DC mappings might have expressions that don't correspond to any single point in the control-flow graph. That makes it trickier to keep track of which expressions should expect an `ExpressionUsed` node.

We therefore sidestep that complexity by only performing `ExpressionUsed` simplification for expressions associated directly with ordinary `Code` mappings.

(This simplification step is inherited from the original coverage implementation, which only supported `Code` mappings anyway, so there's no particular reason to extend it to other kinds of mappings unless we specifically choose to.)

Relevant to:
- rust-lang#124154
- rust-lang#126677
- rust-lang#124278

`@rustbot` label +A-code-coverage
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Jul 15, 2024
coverage: Restrict `ExpressionUsed` simplification to `Code` mappings

In the future, branch and MC/DC mappings might have expressions that don't correspond to any single point in the control-flow graph. That makes it trickier to keep track of which expressions should expect an `ExpressionUsed` node.

We therefore sidestep that complexity by only performing `ExpressionUsed` simplification for expressions associated directly with ordinary `Code` mappings.

(This simplification step is inherited from the original coverage implementation, which only supported `Code` mappings anyway, so there's no particular reason to extend it to other kinds of mappings unless we specifically choose to.)

Relevant to:
- rust-lang#124154
- rust-lang#126677
- rust-lang#124278

``@rustbot`` label +A-code-coverage
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Jul 15, 2024
coverage: Restrict `ExpressionUsed` simplification to `Code` mappings

In the future, branch and MC/DC mappings might have expressions that don't correspond to any single point in the control-flow graph. That makes it trickier to keep track of which expressions should expect an `ExpressionUsed` node.

We therefore sidestep that complexity by only performing `ExpressionUsed` simplification for expressions associated directly with ordinary `Code` mappings.

(This simplification step is inherited from the original coverage implementation, which only supported `Code` mappings anyway, so there's no particular reason to extend it to other kinds of mappings unless we specifically choose to.)

Relevant to:
- rust-lang#124154
- rust-lang#126677
- rust-lang#124278

```@rustbot``` label +A-code-coverage
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Jul 15, 2024
Rollup merge of rust-lang#127758 - Zalathar:expression-used, r=oli-obk

coverage: Restrict `ExpressionUsed` simplification to `Code` mappings

In the future, branch and MC/DC mappings might have expressions that don't correspond to any single point in the control-flow graph. That makes it trickier to keep track of which expressions should expect an `ExpressionUsed` node.

We therefore sidestep that complexity by only performing `ExpressionUsed` simplification for expressions associated directly with ordinary `Code` mappings.

(This simplification step is inherited from the original coverage implementation, which only supported `Code` mappings anyway, so there's no particular reason to extend it to other kinds of mappings unless we specifically choose to.)

Relevant to:
- rust-lang#124154
- rust-lang#126677
- rust-lang#124278

```@rustbot``` label +A-code-coverage
@bors
Copy link
Contributor

bors commented Jul 16, 2024

☔ The latest upstream changes (presumably #127796) made this pull request unmergeable. Please resolve the merge conflicts.

@JohnCSimon
Copy link
Member

@ZhuUx
ping from triage - can you post your status on this PR? This PR has not received an update in a few months and you have merge conflicts

@ZhuUx
Copy link
Contributor Author

ZhuUx commented Sep 4, 2024

@ZhuUx ping from triage - can you post your status on this PR? This PR has not received an update in a few months and you have merge conflicts

Updated to non-conflicted version. Sorry I am trying to fix a bug that with certain -C metadata rustc would panic on some async functions after resolving conflicts. Also this pr is blocked by #126733 . So there is still some work to do.

@rust-log-analyzer

This comment has been minimized.

@bors
Copy link
Contributor

bors commented Sep 10, 2024

☔ The latest upstream changes (presumably #130200) made this pull request unmergeable. Please resolve the merge conflicts.

@ZhuUx
Copy link
Contributor Author

ZhuUx commented Oct 9, 2024

Rebased to the latest since #126733 has been merged.

r? @Zalathar

Nevertheless I would suggest delaying this pr if we are going to refactor lower_match_arms further.
And two known issues worth noting as follows. LLVM-20 will fix the two issues.

@rustbot rustbot assigned Zalathar and unassigned wesleywiser Oct 9, 2024
@Dylan-DPC Dylan-DPC added S-blocked Status: Blocked on something else such as an RFC or other implementation work. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Oct 23, 2024
@bors
Copy link
Contributor

bors commented Oct 25, 2024

☔ The latest upstream changes (presumably #132128) made this pull request unmergeable. Please resolve the merge conflicts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-code-coverage Area: Source-based code coverage (-Cinstrument-coverage) S-blocked Status: Blocked on something else such as an RFC or other implementation work. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants