diff options
| author | bors <bors@rust-lang.org> | 2024-04-03 20:19:51 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-04-03 20:19:51 +0000 |
| commit | 4fd4797c2654977f545c9a91e2aa4e6cdbb38919 (patch) | |
| tree | 90be0d0aff23ef614454b62bc025407392534071 /compiler/rustc_pattern_analysis/src/constructor.rs | |
| parent | 98efd808e1b77cd70a097620aad6250727167a28 (diff) | |
| parent | 65398c46b8207fb36d85bdab1ff2d68c38f0e3a4 (diff) | |
| download | rust-4fd4797c2654977f545c9a91e2aa4e6cdbb38919.tar.gz rust-4fd4797c2654977f545c9a91e2aa4e6cdbb38919.zip | |
Auto merge of #123429 - matthiaskrgr:rollup-4emw4e9, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #121595 (Better reporting on generic argument mismatchs) - #122619 (Fix some unsoundness with PassMode::Cast ABI) - #122964 (Rename `expose_addr` to `expose_provenance`) - #123291 (Move some tests) - #123301 (pattern analysis: fix union handling) - #123395 (More postfix match fixes) - #123419 (rustc_index: Add a `ZERO` constant to index types) - #123421 (Fix target name in NetBSD platform-support doc) r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_pattern_analysis/src/constructor.rs')
| -rw-r--r-- | compiler/rustc_pattern_analysis/src/constructor.rs | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/compiler/rustc_pattern_analysis/src/constructor.rs b/compiler/rustc_pattern_analysis/src/constructor.rs index 1c9a9ab0f72..44f09b66bf6 100644 --- a/compiler/rustc_pattern_analysis/src/constructor.rs +++ b/compiler/rustc_pattern_analysis/src/constructor.rs @@ -140,6 +140,34 @@ //! [`ConstructorSet::split`]. The invariants of [`SplitConstructorSet`] are also of interest. //! //! +//! ## Unions +//! +//! Unions allow us to match a value via several overlapping representations at the same time. For +//! example, the following is exhaustive because when seeing the value as a boolean we handled all +//! possible cases (other cases such as `n == 3` would trigger UB). +//! +//! ```rust +//! # fn main() { +//! union U8AsBool { +//! n: u8, +//! b: bool, +//! } +//! let x = U8AsBool { n: 1 }; +//! unsafe { +//! match x { +//! U8AsBool { n: 2 } => {} +//! U8AsBool { b: true } => {} +//! U8AsBool { b: false } => {} +//! } +//! } +//! # } +//! ``` +//! +//! Pattern-matching has no knowledge that e.g. `false as u8 == 0`, so the values we consider in the +//! algorithm look like `U8AsBool { b: true, n: 2 }`. In other words, for the most part a union is +//! treated like a struct with the same fields. The difference lies in how we construct witnesses of +//! non-exhaustiveness. +//! //! //! ## Opaque patterns //! @@ -974,7 +1002,6 @@ impl<Cx: PatCx> ConstructorSet<Cx> { /// any) are missing; 2/ split constructors to handle non-trivial intersections e.g. on ranges /// or slices. This can get subtle; see [`SplitConstructorSet`] for details of this operation /// and its invariants. - #[instrument(level = "debug", skip(self, ctors), ret)] pub fn split<'a>( &self, ctors: impl Iterator<Item = &'a Constructor<Cx>> + Clone, |
