-
-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Unintuitive pattern evaluation order of or-patterns and union patterns. #158387
Copy link
Copy link
Open
Labels
A-MIRArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlA-patternsRelating to patterns and pattern matchingRelating to patterns and pattern matchingC-bugCategory: This is a bug.Category: This is a bug.I-lang-docs-nominatedNominated for discussion during a lang-docs team meeting.Nominated for discussion during a lang-docs team meeting.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamRelevant to the language teamT-lang-docsRelevant to the lang-docs team.Relevant to the lang-docs team.T-opsemRelevant to the opsem teamRelevant to the opsem teamneeds-triageThis issue may need triage. Remove it if it has been sufficiently triaged.This issue may need triage. Remove it if it has been sufficiently triaged.
Description
Metadata
Metadata
Assignees
Labels
A-MIRArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlA-patternsRelating to patterns and pattern matchingRelating to patterns and pattern matchingC-bugCategory: This is a bug.Category: This is a bug.I-lang-docs-nominatedNominated for discussion during a lang-docs team meeting.Nominated for discussion during a lang-docs team meeting.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamRelevant to the language teamT-lang-docsRelevant to the lang-docs team.Relevant to the lang-docs team.T-opsemRelevant to the opsem teamRelevant to the opsem teamneeds-triageThis issue may need triage. Remove it if it has been sufficiently triaged.This issue may need triage. Remove it if it has been sufficiently triaged.
Type
Fields
No fields configured for issues without a type.
View all comments
This issue is a consequence of rust-lang/unsafe-code-guidelines#540.
When a user has a DIY discriminated union (e.g., for FFI), the user might have a struct containing an enum (the tag) and a union (the payload data). When dealing with such a construction, the reference recommends using pattern-matching to match both the tag and the data in the same pattern. In order for this to not be UB, this relies on the compiler checking the pattern from left to right. (In a struct pattern, it checks the fields in the same order they're mentioned, and short-circuits if anything doesn't match.)
However, as discovered by @steffahn , or-patterns can cause the compiler to change the order that things are matched. This is undocumented, and extremely surprising, if not outright a bug. When combined with the aforementioned construction with unions, this can cause benign-looking code to have UB.
For example, consider the following code:
This code has code that I think looks reasonable, since the
is_integer_zerofunction body is very similar to the aforementioned code pattern recommended by the reference. The only relevant difference is that it uses a single pattern to match against multiple tag values at once. This causes the compiler to emit a read to theintegerfield before ever checking thetagfield. As a result, the above code has UB.Miri output
MIR of is_integer_zero
cc @Nadrieril @RalfJung
Meta
Reproducible on the playground with version
1.98.0-nightly (2026-06-23 f28ac764c36004fa6a6e)