about summary refs log tree commit diff
path: root/compiler/rustc_pattern_analysis/src/constructor.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-04-03 20:19:51 +0000
committerbors <bors@rust-lang.org>2024-04-03 20:19:51 +0000
commit4fd4797c2654977f545c9a91e2aa4e6cdbb38919 (patch)
tree90be0d0aff23ef614454b62bc025407392534071 /compiler/rustc_pattern_analysis/src/constructor.rs
parent98efd808e1b77cd70a097620aad6250727167a28 (diff)
parent65398c46b8207fb36d85bdab1ff2d68c38f0e3a4 (diff)
downloadrust-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.rs29
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,