mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 16:54:01 +00:00
Document how constants as opaque patterns behave differently.
This commit is contained in:
parent
87f9f99f9c
commit
228225842b
@ -844,8 +844,8 @@ impl<'tcx> Constructor<'tcx> {
|
||||
}
|
||||
|
||||
/// Faster version of `is_covered_by` when applied to many constructors. `used_ctors` is
|
||||
/// assumed to be built from `matrix.head_ctors()` with wildcards filtered out, and `self` is
|
||||
/// assumed to have been split from a wildcard.
|
||||
/// assumed to be built from `matrix.head_ctors()` with wildcards and opaques filtered out,
|
||||
/// and `self` is assumed to have been split from a wildcard.
|
||||
fn is_covered_by_any<'p>(
|
||||
&self,
|
||||
pcx: &PatCtxt<'_, 'p, 'tcx>,
|
||||
@ -894,7 +894,7 @@ impl<'tcx> Constructor<'tcx> {
|
||||
/// in `to_ctors`: in some cases we only return `Missing`.
|
||||
#[derive(Debug)]
|
||||
pub(super) struct SplitWildcard<'tcx> {
|
||||
/// Constructors seen in the matrix.
|
||||
/// Constructors (other than wildcards and opaques) seen in the matrix.
|
||||
matrix_ctors: Vec<Constructor<'tcx>>,
|
||||
/// All the constructors for this type
|
||||
all_ctors: SmallVec<[Constructor<'tcx>; 1]>,
|
||||
@ -1037,7 +1037,7 @@ impl<'tcx> SplitWildcard<'tcx> {
|
||||
// Since `all_ctors` never contains wildcards, this won't recurse further.
|
||||
self.all_ctors =
|
||||
self.all_ctors.iter().flat_map(|ctor| ctor.split(pcx, ctors.clone())).collect();
|
||||
self.matrix_ctors = ctors.filter(|c| !c.is_wildcard()).cloned().collect();
|
||||
self.matrix_ctors = ctors.filter(|c| !matches!(c, Wildcard | Opaque)).cloned().collect();
|
||||
}
|
||||
|
||||
/// Whether there are any value constructors for this type that are not present in the matrix.
|
||||
|
@ -288,6 +288,22 @@
|
||||
//!
|
||||
//! The details are not necessary to understand this file, so we explain them in
|
||||
//! [`super::deconstruct_pat`]. Splitting is done by the [`Constructor::split`] function.
|
||||
//!
|
||||
//! # Constants in patterns
|
||||
//!
|
||||
//! There are two kinds of constants in patterns:
|
||||
//!
|
||||
//! * literals (`1`, `true`, `"foo"`)
|
||||
//! * named or inline consts (`FOO`, `const { 5 + 6 }`)
|
||||
//!
|
||||
//! The latter are converted into other patterns with literals at the leaves. For example
|
||||
//! `const_to_pat(const { [1, 2, 3] })` becomes an `Array(vec![Const(1), Const(2), Const(3)])`
|
||||
//! pattern. This gets problematic when comparing the constant via `==` would behave differently
|
||||
//! from matching on the constant converted to a pattern. Situations like that can occur, when
|
||||
//! the user implements `PartialEq` manually, and thus could make `==` behave arbitrarily different.
|
||||
//! In order to honor the `==` implementation, constants of types that implement `PartialEq` manually
|
||||
//! stay as a full constant and become an `Opaque` pattern. These `Opaque` patterns do not participate
|
||||
//! in exhaustiveness, specialization or overlap checking.
|
||||
|
||||
use self::ArmType::*;
|
||||
use self::Usefulness::*;
|
||||
|
Loading…
Reference in New Issue
Block a user