Description
Recently it was pointed out to me that there is an entire category of const-related soundness concerns that I was unaware of, and that is not mentioned with a single word in this repository: pattern matching. I think for the most part, const soundness and "const FOO = expr
is equivalent to inlining expr
" suffice to ensure pattern-matching-soundness, but there is one exception: const-soundness as described and discussed so far stops at references, but when pattern-matching on consts, the content behind the reference can matter.
For example, the following is completely fine as far as "inlining-soundness" is concerned, but it is pattern-unsound (and let's ignore aliasing issues for now):
static mut BYTES: [u8; 16] = *b"1234567890abcdef";
const BYTES_REF: &[u8] = unsafe { &BYTES };
fn main() { unsafe {
BYTES[0] = 2;
assert!(matches!(b"1234567890abcdef", BYTES_REF));
} }
Inlining semantics are entirely preserved when a const just points to mutable data, but the same becomes a big problem with pattern matching.
Some things I think we should do:
- Have a document describing pattern-matching-soundness concerns in this repository (Cc add document on consts in patterns #48). For this, determine how const-patterns are compiled and which of they participate in exhaustiveness checking.
- Improve our dynamic checks for pattern-matching-soundness (aka "consts are immutable") to avoid relying on a global invariant.
- Maybe restrict patterns to types with a good notion of equality? That would exclude function pointers and raw pointers.