about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOli Scherer <github333195615777966@oli-obk.de>2025-02-02 17:54:35 +0000
committerOli Scherer <github333195615777966@oli-obk.de>2025-02-02 19:30:53 +0000
commitded0836c18a0b25f076ee776e1c9eeb989272f3b (patch)
treefda26aaf4de1fbd14636dfbc25e274c9ff87739a
parent2f2b32b84e778669e06be5e37643f21ba98bedc8 (diff)
downloadrust-ded0836c18a0b25f076ee776e1c9eeb989272f3b.tar.gz
rust-ded0836c18a0b25f076ee776e1c9eeb989272f3b.zip
Check the base type of pattern types for validity first
-rw-r--r--compiler/rustc_const_eval/src/interpret/validity.rs9
-rw-r--r--tests/ui/type/pattern_types/validity.stderr2
2 files changed, 5 insertions, 6 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index 649a759bc8b..8e544798742 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -4,7 +4,6 @@
 //! That's useful because it means other passes (e.g. promotion) can rely on `const`s
 //! to be const-safe.
 
-use std::assert_matches::assert_matches;
 use std::borrow::Cow;
 use std::fmt::Write;
 use std::hash::Hash;
@@ -1241,15 +1240,15 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt,
                     self.visit_field(val, 0, &self.ecx.project_index(val, 0)?)?;
                 }
             }
-            ty::Pat(_base, pat) => {
+            ty::Pat(base, pat) => {
+                // First check that the base type is valid
+                self.visit_value(&val.transmute(self.ecx.layout_of(*base)?, self.ecx)?)?;
                 // When you extend this match, make sure to also add tests to
                 // tests/ui/type/pattern_types/validity.rs((
                 match **pat {
                     // Range patterns are precisely reflected into `valid_range` and thus
                     // handled fully by `visit_scalar` (called below).
-                    ty::PatternKind::Range { .. } => {
-                        assert_matches!(val.layout.backend_repr, BackendRepr::Scalar(_));
-                    },
+                    ty::PatternKind::Range { .. } => {},
                 }
             }
             _ => {
diff --git a/tests/ui/type/pattern_types/validity.stderr b/tests/ui/type/pattern_types/validity.stderr
index 21b7792b83e..5bc18cfba3f 100644
--- a/tests/ui/type/pattern_types/validity.stderr
+++ b/tests/ui/type/pattern_types/validity.stderr
@@ -67,7 +67,7 @@ error[E0080]: it is undefined behavior to use this value
   --> $DIR/validity.rs:34:1
    |
 LL | const CHAR_OOB: pattern_type!(char is 'A'..'Z') = unsafe { std::mem::transmute(u32::MAX) };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 4294967295, but expected something in the range 65..=89
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {