Repository navigation
[release/stable] Emit correct IL for exhaustive switch statements that use a separate Dag for lowering - #86251
Merged
Conversation
|
Azure Pipelines: Successfully started running 1 pipeline(s). 1 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
RikkiGibson
approved these changes
Oct 29, 2026
Contributor
There was a problem hiding this comment.
🔵 Needs a closer look
Compiler-owner validation is needed because this release-branch change affects control-flow lowering and emitted IL, but its Debug/Release execution and IL-verification tests could not be run in the review environment.
No open issues 🎉
What changed in this PR
Backports #85873 to release/stable, correcting C# IL emission when an exhaustive switch statement uses a separate decision graph for lowering. The fix adds a terminating throw for unmatched paths introduced by lowering while preserving explicit goto default behavior.
Changes:
- Detects fallback labels that become reachable only during lowering and emits an exception throw.
- Shares exception-selection and throw-construction logic with switch-expression lowering.
- Adds 18 regression tests for unions and list patterns, plus an assertion that an existing case emits no unnecessary throw.
| File | Description |
|---|---|
src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs |
Updates the decision-graph helper call for the new output parameter. |
src/Compilers/CSharp/Test/Emit3/Semantics/PatternMatchingTests_ListPatterns.cs |
Adds exhaustive list-pattern tests and IL assertions. |
src/Compilers/CSharp/Test/CSharp15/UnionsTests.cs |
Adds 16 union-switch regression tests covering control flow and exception fallbacks. |
src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedThrowSwitchExpressionExceptionMethod.cs |
Extracts reusable throw construction with the unmatched value. |
src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedParameterlessThrowMethod.cs |
Extracts reusable parameterless exception throw construction. |
src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_SwitchExpression.cs |
Uses the shared exception-selection strategy. |
src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_PatternSwitchStatement.cs |
Emits throws at fallback labels introduced by lowering. |
src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_BasePatternSwitchLocalRewriter.cs |
Centralizes exception selection and input-conversion checks. |
src/Compilers/CSharp/Portable/BoundTree/BoundSwitchStatement.cs |
Identifies lowering-only fallback paths without redirecting explicit default-label jumps. |
Review effort: Balanced
333fred
approved these changes
Oct 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Backport of #85873 to release/stable
/cc @AlekseyTs
Customer Impact
Reported by internal and external users of Unions feature.
Regression
Testing
18 unit tests were added for various scenarios.
The issue was missed previously because we were missing a test for an exhaustive switch statement utilizing separate decision Dag for lowering, which was used at the end of a method. In previous version, a separate lowering Dag was used only for some scenarios involving list patterns. When unions feature is used, usage of a lowering Dag is fairly common.
Risk
Low. We now have a pretty comprehensive set of unit-tests covering the scenario. Two senior compiler developers reviewed the change. Copilot review didn't find any issues.
Microsoft Reviewers: Open in CodeFlow