about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2023-09-16 09:09:25 +0200
committerRalf Jung <post@ralfj.de>2023-09-16 12:25:33 +0200
commitd34e15e740633e5329672ccea90e19e09e53c7f4 (patch)
treeb9b3fd931619a4e51df0fc48d3b8a0bcc2cd8952
parent635c4a5e612b0ee8af6615635599702d3dce9906 (diff)
downloadrust-d34e15e740633e5329672ccea90e19e09e53c7f4.tar.gz
rust-d34e15e740633e5329672ccea90e19e09e53c7f4.zip
thir::pattern: update some comments and error type names
-rw-r--r--compiler/rustc_middle/src/thir.rs16
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs25
2 files changed, 24 insertions, 17 deletions
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index ebc1c11902b..fb9793b3181 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -732,12 +732,16 @@ pub enum PatKind<'tcx> {
     },
 
     /// One of the following:
-    /// * `&str`, which will be handled as a string pattern and thus exhaustiveness
-    ///   checking will detect if you use the same string twice in different patterns.
-    /// * integer, bool, char or float, which will be handled by exhaustiveness to cover exactly
-    ///   its own value, similar to `&str`, but these values are much simpler.
-    /// * Opaque constants, that must not be matched structurally. So anything that does not derive
-    ///   `PartialEq` and `Eq`.
+    /// * `&str` (represented as a valtree), which will be handled as a string pattern and thus
+    ///   exhaustiveness checking will detect if you use the same string twice in different
+    ///   patterns.
+    /// * integer, bool, char or float (represented as a valtree), which will be handled by
+    ///   exhaustiveness to cover exactly its own value, similar to `&str`, but these values are
+    ///   much simpler.
+    /// * Opaque constants (represented as `mir::ConstValue`), that must not be matched
+    ///   structurally. So anything that does not derive `PartialEq` and `Eq`.
+    ///
+    /// These are always compared with the matched place using (the semantics of) `PartialEq`.
     Constant {
         value: mir::ConstantKind<'tcx>,
     },
diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
index 1376344cfda..9e2a725e7e6 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
@@ -24,6 +24,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
     /// Converts an evaluated constant to a pattern (if possible).
     /// This means aggregate values (like structs and enums) are converted
     /// to a pattern that matches the value (as if you'd compared via structural equality).
+    ///
+    /// `cv` must be a valtree or a `mir::ConstValue`.
     #[instrument(level = "debug", skip(self), ret)]
     pub(super) fn const_to_pat(
         &self,
@@ -64,12 +66,8 @@ struct ConstToPat<'tcx> {
 }
 
 /// This error type signals that we encountered a non-struct-eq situation.
-/// We bubble this up in order to get back to the reference destructuring and make that emit
-/// a const pattern instead of a deref pattern. This allows us to simply call `PartialEq::eq`
-/// on such patterns (since that function takes a reference) and not have to jump through any
-/// hoops to get a reference to the value.
 #[derive(Debug)]
-struct FallbackToConstRef;
+struct FallbackToOpaqueConst;
 
 impl<'tcx> ConstToPat<'tcx> {
     fn new(
@@ -136,7 +134,7 @@ impl<'tcx> ConstToPat<'tcx> {
                 }
                 ty::ConstKind::Value(valtree) => self
                     .recur(valtree, cv.ty(), mir_structural_match_violation.unwrap_or(false))
-                    .unwrap_or_else(|_| {
+                    .unwrap_or_else(|_: FallbackToOpaqueConst| {
                         Box::new(Pat {
                             span: self.span,
                             ty: cv.ty(),
@@ -266,7 +264,7 @@ impl<'tcx> ConstToPat<'tcx> {
     fn field_pats(
         &self,
         vals: impl Iterator<Item = (ValTree<'tcx>, Ty<'tcx>)>,
-    ) -> Result<Vec<FieldPat<'tcx>>, FallbackToConstRef> {
+    ) -> Result<Vec<FieldPat<'tcx>>, FallbackToOpaqueConst> {
         vals.enumerate()
             .map(|(idx, (val, ty))| {
                 let field = FieldIdx::new(idx);
@@ -284,7 +282,7 @@ impl<'tcx> ConstToPat<'tcx> {
         cv: ValTree<'tcx>,
         ty: Ty<'tcx>,
         mir_structural_match_violation: bool,
-    ) -> Result<Box<Pat<'tcx>>, FallbackToConstRef> {
+    ) -> Result<Box<Pat<'tcx>>, FallbackToOpaqueConst> {
         let id = self.id;
         let span = self.span;
         let tcx = self.tcx();
@@ -299,7 +297,7 @@ impl<'tcx> ConstToPat<'tcx> {
                     span,
                     FloatPattern,
                 );
-                return Err(FallbackToConstRef);
+                return Err(FallbackToOpaqueConst);
             }
             // If the type is not structurally comparable, just emit the constant directly,
             // causing the pattern match code to treat it opaquely.
@@ -323,11 +321,12 @@ impl<'tcx> ConstToPat<'tcx> {
                 // Since we are behind a reference, we can just bubble the error up so we get a
                 // constant at reference type, making it easy to let the fallback call
                 // `PartialEq::eq` on it.
-                return Err(FallbackToConstRef);
+                return Err(FallbackToOpaqueConst);
             }
             ty::FnDef(..) => {
                 self.saw_const_match_error.set(true);
                 tcx.sess.emit_err(InvalidPattern { span, non_sm_ty: ty });
+                // We errored, so the pattern we generate is irrelevant.
                 PatKind::Wild
             }
             ty::Adt(adt_def, _) if !self.type_marked_structural(ty) => {
@@ -335,6 +334,7 @@ impl<'tcx> ConstToPat<'tcx> {
                 self.saw_const_match_error.set(true);
                 let err = TypeNotStructural { span, non_sm_ty: ty };
                 tcx.sess.emit_err(err);
+                // We errored, so the pattern we generate is irrelevant.
                 PatKind::Wild
             }
             ty::Adt(adt_def, args) if adt_def.is_enum() => {
@@ -404,13 +404,14 @@ impl<'tcx> ConstToPat<'tcx> {
                                 IndirectStructuralMatch { non_sm_ty: *pointee_ty },
                             );
                         }
-                        return Err(FallbackToConstRef);
+                        return Err(FallbackToOpaqueConst);
                     } else {
                         if !self.saw_const_match_error.get() {
                             self.saw_const_match_error.set(true);
                             let err = TypeNotStructural { span, non_sm_ty: *pointee_ty };
                             tcx.sess.emit_err(err);
                         }
+                        // We errored, so the pattern we generate is irrelevant.
                         PatKind::Wild
                     }
                 }
@@ -423,6 +424,7 @@ impl<'tcx> ConstToPat<'tcx> {
                         tcx.sess.emit_err(err);
 
                         // FIXME: introduce PatKind::Error to silence follow up diagnostics due to unreachable patterns.
+                        // We errored, so the pattern we generate is irrelevant.
                         PatKind::Wild
                     } else {
                         let old = self.behind_reference.replace(true);
@@ -453,6 +455,7 @@ impl<'tcx> ConstToPat<'tcx> {
                 self.saw_const_match_error.set(true);
                 let err = InvalidPattern { span, non_sm_ty: ty };
                 tcx.sess.emit_err(err);
+                // We errored, so the pattern we generate is irrelevant.
                 PatKind::Wild
             }
         };