dslx: reject duplicate match alternatives - #4731
Open
dank-openai wants to merge 1 commit into
Open
Conversation
* dslx: reject duplicate match alternatives with both source locations
## Summary
- Reject duplicate match patterns even when an occurrence is embedded in a `|`-separated alternative.
- Highlight both the original and duplicate source locations in the compiler error.
- Preserve valid grouped alternatives and existing duplicate-arm checks.
- Preserve a disabled regression for the separate pre-existing case where an enum type alias gives the same variant two spellings.
## Problem Solved
DSLX compared complete match arms when checking for duplicates. Consequently, an enum variant could appear in separate arms and the match would still compile:
```dslx
match value {
E::A => u32:0,
E::B | E::A => u32:1,
E::C => u32:2,
}
```
The second `E::A` can never match, hiding unreachable code and copy-and-paste mistakes. This change rejects the program with a `TypeInferenceError` and reports both occurrences.
## Implementation
Track individual top-level match alternatives alongside the existing whole-arm duplicate check. Retain the first occurrence so the error can name its location and attach both source spans to the diagnostic.
Programs that previously compiled with duplicate exact match alternatives now intentionally fail compilation. Valid grouped alternatives and existing range or tuple overlap behavior remain unchanged.
Enum type aliases such as `type Alias = E;` can still spell the same member as `E::A` and `Alias::A`. That pre-existing semantic-equivalence case is intentionally not fixed here; a repository-conventional `DISABLED_` regression records the failing behavior for future work.
## Testing
- `bazel test //xls/dslx/type_system_v2:typecheck_module_v2_control_flow_test //xls/dslx/exhaustiveness:exhaustiveness_match_test //xls/dslx/type_system:typecheck_module_test`
- Regression coverage verifies both source spans, rejects the reported enum pattern, and accepts unique grouped alternatives.
- Direct compiler checks cover the checked-in diagnostic fixture, existing whole-arm duplicates, and non-exhaustive enum matches.
- Forcing `DISABLED_MatchEnumVariantDuplicatedThroughTypeAlias` to run with `--gtest_also_run_disabled_tests` fails as expected; normal execution passes 100 control-flow tests and reports one disabled test.
* dslx: explain unresolved duplicate enum-alias match cases
E::A and Alias::A denote the same enum member after type Alias = E,
but match validation compares source spellings and incorrectly accepts
an unreachable duplicate arm.
Record beside the disabled regression that fixing this requires
resolving enum-member identity before comparing match patterns.
dank-openai
added a commit
to xlsynth/xlsynth
that referenced
this pull request
Aug 6, 2026
* dslx: reject duplicate match alternatives with both source locations
## Summary
- Reject duplicate match patterns even when an occurrence is embedded in a `|`-separated alternative.
- Highlight both the original and duplicate source locations in the compiler error.
- Preserve valid grouped alternatives and existing duplicate-arm checks.
- Preserve a disabled regression for the separate pre-existing case where an enum type alias gives the same variant two spellings.
## Problem Solved
DSLX compared complete match arms when checking for duplicates. Consequently, an enum variant could appear in separate arms and the match would still compile:
```dslx
match value {
E::A => u32:0,
E::B | E::A => u32:1,
E::C => u32:2,
}
```
The second `E::A` can never match, hiding unreachable code and copy-and-paste mistakes. This change rejects the program with a `TypeInferenceError` and reports both occurrences.
## Implementation
Track individual top-level match alternatives alongside the existing whole-arm duplicate check. Retain the first occurrence so the error can name its location and attach both source spans to the diagnostic.
Programs that previously compiled with duplicate exact match alternatives now intentionally fail compilation. Valid grouped alternatives and existing range or tuple overlap behavior remain unchanged.
Enum type aliases such as `type Alias = E;` can still spell the same member as `E::A` and `Alias::A`. That pre-existing semantic-equivalence case is intentionally not fixed here; a repository-conventional `DISABLED_` regression records the failing behavior for future work.
## Testing
- `bazel test //xls/dslx/type_system_v2:typecheck_module_v2_control_flow_test //xls/dslx/exhaustiveness:exhaustiveness_match_test //xls/dslx/type_system:typecheck_module_test`
- Regression coverage verifies both source spans, rejects the reported enum pattern, and accepts unique grouped alternatives.
- Direct compiler checks cover the checked-in diagnostic fixture, existing whole-arm duplicates, and non-exhaustive enum matches.
- Forcing `DISABLED_MatchEnumVariantDuplicatedThroughTypeAlias` to run with `--gtest_also_run_disabled_tests` fails as expected; normal execution passes 100 control-flow tests and reports one disabled test.
* dslx: explain unresolved duplicate enum-alias match cases
E::A and Alias::A denote the same enum member after type Alias = E,
but match validation compares source spellings and incorrectly accepts
an unreachable duplicate arm.
Record beside the disabled regression that fixing this requires
resolving enum-member identity before comparing match patterns.
dank-openai
force-pushed
the
dank/wip/upstream-dslx-duplicate-match-alternatives-0806
branch
from
August 6, 2026 21:26
b35f5ad to
dd96cea
Compare
dank-openai
added a commit
to xlsynth/xlsynth
that referenced
this pull request
Aug 6, 2026
Store first-occurrence source spans directly instead of PatternTree pointers. This keeps duplicate-pattern and enum-alias diagnostics synchronized with Google XLS PRs google#4731 and google#4732 without changing their reported locations.
dank-openai
added a commit
to xlsynth/xlsynth
that referenced
this pull request
Aug 6, 2026
* dslx: reject duplicate match alternatives with both source locations
## Summary
- Reject duplicate match patterns even when an occurrence is embedded in a `|`-separated alternative.
- Highlight both the original and duplicate source locations in the compiler error.
- Preserve valid grouped alternatives and existing duplicate-arm checks.
- Preserve a disabled regression for the separate pre-existing case where an enum type alias gives the same variant two spellings.
## Problem Solved
DSLX compared complete match arms when checking for duplicates. Consequently, an enum variant could appear in separate arms and the match would still compile:
```dslx
match value {
E::A => u32:0,
E::B | E::A => u32:1,
E::C => u32:2,
}
```
The second `E::A` can never match, hiding unreachable code and copy-and-paste mistakes. This change rejects the program with a `TypeInferenceError` and reports both occurrences.
## Implementation
Track individual top-level match alternatives alongside the existing whole-arm duplicate check. Retain the first occurrence so the error can name its location and attach both source spans to the diagnostic.
Programs that previously compiled with duplicate exact match alternatives now intentionally fail compilation. Valid grouped alternatives and existing range or tuple overlap behavior remain unchanged.
Enum type aliases such as `type Alias = E;` can still spell the same member as `E::A` and `Alias::A`. That pre-existing semantic-equivalence case is intentionally not fixed here; a repository-conventional `DISABLED_` regression records the failing behavior for future work.
## Testing
- `bazel test //xls/dslx/type_system_v2:typecheck_module_v2_control_flow_test //xls/dslx/exhaustiveness:exhaustiveness_match_test //xls/dslx/type_system:typecheck_module_test`
- Regression coverage verifies both source spans, rejects the reported enum pattern, and accepts unique grouped alternatives.
- Direct compiler checks cover the checked-in diagnostic fixture, existing whole-arm duplicates, and non-exhaustive enum matches.
- Forcing `DISABLED_MatchEnumVariantDuplicatedThroughTypeAlias` to run with `--gtest_also_run_disabled_tests` fails as expected; normal execution passes 100 control-flow tests and reports one disabled test.
* dslx: explain unresolved duplicate enum-alias match cases
E::A and Alias::A denote the same enum member after type Alias = E,
but match validation compares source spellings and incorrectly accepts
an unreachable duplicate arm.
Record beside the disabled regression that fixing this requires
resolving enum-member identity before comparing match patterns.
dank-openai
added a commit
to xlsynth/xlsynth
that referenced
this pull request
Aug 6, 2026
Store first-occurrence source spans directly instead of PatternTree pointers. This keeps duplicate-pattern and enum-alias diagnostics synchronized with Google XLS PRs google#4731 and google#4732 without changing their reported locations.
dank-openai
added a commit
to xlsynth/xlsynth
that referenced
this pull request
Aug 7, 2026
* dslx: reject duplicate match alternatives with both source locations
## Summary
- Reject duplicate match patterns even when an occurrence is embedded in a `|`-separated alternative.
- Highlight both the original and duplicate source locations in the compiler error.
- Preserve valid grouped alternatives and existing duplicate-arm checks.
- Preserve a disabled regression for the separate pre-existing case where an enum type alias gives the same variant two spellings.
## Problem Solved
DSLX compared complete match arms when checking for duplicates. Consequently, an enum variant could appear in separate arms and the match would still compile:
```dslx
match value {
E::A => u32:0,
E::B | E::A => u32:1,
E::C => u32:2,
}
```
The second `E::A` can never match, hiding unreachable code and copy-and-paste mistakes. This change rejects the program with a `TypeInferenceError` and reports both occurrences.
## Implementation
Track individual top-level match alternatives alongside the existing whole-arm duplicate check. Retain the first occurrence so the error can name its location and attach both source spans to the diagnostic.
Programs that previously compiled with duplicate exact match alternatives now intentionally fail compilation. Valid grouped alternatives and existing range or tuple overlap behavior remain unchanged.
Enum type aliases such as `type Alias = E;` can still spell the same member as `E::A` and `Alias::A`. That pre-existing semantic-equivalence case is intentionally not fixed here; a repository-conventional `DISABLED_` regression records the failing behavior for future work.
## Testing
- `bazel test //xls/dslx/type_system_v2:typecheck_module_v2_control_flow_test //xls/dslx/exhaustiveness:exhaustiveness_match_test //xls/dslx/type_system:typecheck_module_test`
- Regression coverage verifies both source spans, rejects the reported enum pattern, and accepts unique grouped alternatives.
- Direct compiler checks cover the checked-in diagnostic fixture, existing whole-arm duplicates, and non-exhaustive enum matches.
- Forcing `DISABLED_MatchEnumVariantDuplicatedThroughTypeAlias` to run with `--gtest_also_run_disabled_tests` fails as expected; normal execution passes 100 control-flow tests and reports one disabled test.
* dslx: explain unresolved duplicate enum-alias match cases
E::A and Alias::A denote the same enum member after type Alias = E,
but match validation compares source spellings and incorrectly accepts
an unreachable duplicate arm.
Record beside the disabled regression that fixing this requires
resolving enum-member identity before comparing match patterns.
dank-openai
added a commit
to xlsynth/xlsynth
that referenced
this pull request
Aug 7, 2026
Store first-occurrence source spans directly instead of PatternTree pointers. This keeps duplicate-pattern and enum-alias diagnostics synchronized with Google XLS PRs google#4731 and google#4732 without changing their reported locations.
dank-openai
added a commit
to xlsynth/xlsynth
that referenced
this pull request
Aug 7, 2026
* dslx: reject duplicate match alternatives with both source locations
## Summary
- Reject duplicate match patterns even when an occurrence is embedded in a `|`-separated alternative.
- Highlight both the original and duplicate source locations in the compiler error.
- Preserve valid grouped alternatives and existing duplicate-arm checks.
- Preserve a disabled regression for the separate pre-existing case where an enum type alias gives the same variant two spellings.
## Problem Solved
DSLX compared complete match arms when checking for duplicates. Consequently, an enum variant could appear in separate arms and the match would still compile:
```dslx
match value {
E::A => u32:0,
E::B | E::A => u32:1,
E::C => u32:2,
}
```
The second `E::A` can never match, hiding unreachable code and copy-and-paste mistakes. This change rejects the program with a `TypeInferenceError` and reports both occurrences.
## Implementation
Track individual top-level match alternatives alongside the existing whole-arm duplicate check. Retain the first occurrence so the error can name its location and attach both source spans to the diagnostic.
Programs that previously compiled with duplicate exact match alternatives now intentionally fail compilation. Valid grouped alternatives and existing range or tuple overlap behavior remain unchanged.
Enum type aliases such as `type Alias = E;` can still spell the same member as `E::A` and `Alias::A`. That pre-existing semantic-equivalence case is intentionally not fixed here; a repository-conventional `DISABLED_` regression records the failing behavior for future work.
## Testing
- `bazel test //xls/dslx/type_system_v2:typecheck_module_v2_control_flow_test //xls/dslx/exhaustiveness:exhaustiveness_match_test //xls/dslx/type_system:typecheck_module_test`
- Regression coverage verifies both source spans, rejects the reported enum pattern, and accepts unique grouped alternatives.
- Direct compiler checks cover the checked-in diagnostic fixture, existing whole-arm duplicates, and non-exhaustive enum matches.
- Forcing `DISABLED_MatchEnumVariantDuplicatedThroughTypeAlias` to run with `--gtest_also_run_disabled_tests` fails as expected; normal execution passes 100 control-flow tests and reports one disabled test.
* dslx: explain unresolved duplicate enum-alias match cases
E::A and Alias::A denote the same enum member after type Alias = E,
but match validation compares source spellings and incorrectly accepts
an unreachable duplicate arm.
Record beside the disabled regression that fixing this requires
resolving enum-member identity before comparing match patterns.
dank-openai
added a commit
to xlsynth/xlsynth
that referenced
this pull request
Aug 7, 2026
Store first-occurrence source spans directly instead of PatternTree pointers. This keeps duplicate-pattern and enum-alias diagnostics synchronized with Google XLS PRs google#4731 and google#4732 without changing their reported locations.
dank-openai
added a commit
to xlsynth/xlsynth
that referenced
this pull request
Aug 7, 2026
* dslx: reject duplicate match alternatives with both source locations
## Summary
- Reject duplicate match patterns even when an occurrence is embedded in a `|`-separated alternative.
- Highlight both the original and duplicate source locations in the compiler error.
- Preserve valid grouped alternatives and existing duplicate-arm checks.
- Preserve a disabled regression for the separate pre-existing case where an enum type alias gives the same variant two spellings.
## Problem Solved
DSLX compared complete match arms when checking for duplicates. Consequently, an enum variant could appear in separate arms and the match would still compile:
```dslx
match value {
E::A => u32:0,
E::B | E::A => u32:1,
E::C => u32:2,
}
```
The second `E::A` can never match, hiding unreachable code and copy-and-paste mistakes. This change rejects the program with a `TypeInferenceError` and reports both occurrences.
## Implementation
Track individual top-level match alternatives alongside the existing whole-arm duplicate check. Retain the first occurrence so the error can name its location and attach both source spans to the diagnostic.
Programs that previously compiled with duplicate exact match alternatives now intentionally fail compilation. Valid grouped alternatives and existing range or tuple overlap behavior remain unchanged.
Enum type aliases such as `type Alias = E;` can still spell the same member as `E::A` and `Alias::A`. That pre-existing semantic-equivalence case is intentionally not fixed here; a repository-conventional `DISABLED_` regression records the failing behavior for future work.
## Testing
- `bazel test //xls/dslx/type_system_v2:typecheck_module_v2_control_flow_test //xls/dslx/exhaustiveness:exhaustiveness_match_test //xls/dslx/type_system:typecheck_module_test`
- Regression coverage verifies both source spans, rejects the reported enum pattern, and accepts unique grouped alternatives.
- Direct compiler checks cover the checked-in diagnostic fixture, existing whole-arm duplicates, and non-exhaustive enum matches.
- Forcing `DISABLED_MatchEnumVariantDuplicatedThroughTypeAlias` to run with `--gtest_also_run_disabled_tests` fails as expected; normal execution passes 100 control-flow tests and reports one disabled test.
* dslx: explain unresolved duplicate enum-alias match cases
E::A and Alias::A denote the same enum member after type Alias = E,
but match validation compares source spellings and incorrectly accepts
an unreachable duplicate arm.
Record beside the disabled regression that fixing this requires
resolving enum-member identity before comparing match patterns.
dank-openai
added a commit
to xlsynth/xlsynth
that referenced
this pull request
Aug 7, 2026
Store first-occurrence source spans directly instead of PatternTree pointers. This keeps duplicate-pattern and enum-alias diagnostics synchronized with Google XLS PRs google#4731 and google#4732 without changing their reported locations.
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.
Summary
|alternatives.Problem
DSLX currently accepts this unreachable second
E::Apattern:The compiler compares entire match arms, so it misses a repeated pattern nested
inside another arm's alternatives. Track the individual alternatives as well,
and report both occurrences when one repeats.
Programs containing exact duplicate alternatives now intentionally fail
compilation. Valid grouped alternatives continue to compile.
The separate pre-existing enum-alias spelling case remains documented by a
disabled regression and is not fixed by this change.
Tests
The equivalent merged producer change passed:
//xls/dslx/type_system_v2:typecheck_module_v2_control_flow_test//xls/dslx/exhaustiveness:exhaustiveness_match_test//xls/dslx/type_system:typecheck_module_testThe added diagnostic fixture is owned by
//xls/dslx/tests/errors:error_modules_test.Current upstream
maincannot start an ordinary Bazel build because itsrules_hdlpatch targets a missing file; the same failure is already presentin upstream main CI.
No unrelated dependency or build-configuration changes are included here.