Skip to content

Commit 2282258

Browse files
committed
Document how constants as opaque patterns behave differently.
1 parent 87f9f99 commit 2282258

File tree

2 files changed

+20
-4
lines changed

2 files changed

+20
-4
lines changed

compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -844,8 +844,8 @@ impl<'tcx> Constructor<'tcx> {
844844
}
845845

846846
/// Faster version of `is_covered_by` when applied to many constructors. `used_ctors` is
847-
/// assumed to be built from `matrix.head_ctors()` with wildcards filtered out, and `self` is
848-
/// assumed to have been split from a wildcard.
847+
/// assumed to be built from `matrix.head_ctors()` with wildcards and opaques filtered out,
848+
/// and `self` is assumed to have been split from a wildcard.
849849
fn is_covered_by_any<'p>(
850850
&self,
851851
pcx: &PatCtxt<'_, 'p, 'tcx>,
@@ -894,7 +894,7 @@ impl<'tcx> Constructor<'tcx> {
894894
/// in `to_ctors`: in some cases we only return `Missing`.
895895
#[derive(Debug)]
896896
pub(super) struct SplitWildcard<'tcx> {
897-
/// Constructors seen in the matrix.
897+
/// Constructors (other than wildcards and opaques) seen in the matrix.
898898
matrix_ctors: Vec<Constructor<'tcx>>,
899899
/// All the constructors for this type
900900
all_ctors: SmallVec<[Constructor<'tcx>; 1]>,
@@ -1037,7 +1037,7 @@ impl<'tcx> SplitWildcard<'tcx> {
10371037
// Since `all_ctors` never contains wildcards, this won't recurse further.
10381038
self.all_ctors =
10391039
self.all_ctors.iter().flat_map(|ctor| ctor.split(pcx, ctors.clone())).collect();
1040-
self.matrix_ctors = ctors.filter(|c| !c.is_wildcard()).cloned().collect();
1040+
self.matrix_ctors = ctors.filter(|c| !matches!(c, Wildcard | Opaque)).cloned().collect();
10411041
}
10421042

10431043
/// Whether there are any value constructors for this type that are not present in the matrix.

compiler/rustc_mir_build/src/thir/pattern/usefulness.rs

+16
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,22 @@
288288
//!
289289
//! The details are not necessary to understand this file, so we explain them in
290290
//! [`super::deconstruct_pat`]. Splitting is done by the [`Constructor::split`] function.
291+
//!
292+
//! # Constants in patterns
293+
//!
294+
//! There are two kinds of constants in patterns:
295+
//!
296+
//! * literals (`1`, `true`, `"foo"`)
297+
//! * named or inline consts (`FOO`, `const { 5 + 6 }`)
298+
//!
299+
//! The latter are converted into other patterns with literals at the leaves. For example
300+
//! `const_to_pat(const { [1, 2, 3] })` becomes an `Array(vec![Const(1), Const(2), Const(3)])`
301+
//! pattern. This gets problematic when comparing the constant via `==` would behave differently
302+
//! from matching on the constant converted to a pattern. Situations like that can occur, when
303+
//! the user implements `PartialEq` manually, and thus could make `==` behave arbitrarily different.
304+
//! In order to honor the `==` implementation, constants of types that implement `PartialEq` manually
305+
//! stay as a full constant and become an `Opaque` pattern. These `Opaque` patterns do not participate
306+
//! in exhaustiveness, specialization or overlap checking.
291307
292308
use self::ArmType::*;
293309
use self::Usefulness::*;

0 commit comments

Comments
 (0)