about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs28
1 files changed, 15 insertions, 13 deletions
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 8ef4ba5d189..fde6defd87f 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
@@ -7,7 +7,7 @@ use rustc_middle::mir;
 use rustc_middle::thir::{FieldPat, Pat, PatKind};
 use rustc_middle::ty::{self, Ty, TyCtxt, ValTree};
 use rustc_session::lint;
-use rustc_span::Span;
+use rustc_span::{ErrorGuaranteed, Span};
 use rustc_target::abi::{FieldIdx, VariantIdx};
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
 use rustc_trait_selection::traits::{self, ObligationCause};
@@ -48,7 +48,7 @@ struct ConstToPat<'tcx> {
     // This tracks if we emitted some hard error for a given const value, so that
     // we will not subsequently issue an irrelevant lint for the same const
     // value.
-    saw_const_match_error: Cell<bool>,
+    saw_const_match_error: Cell<Option<ErrorGuaranteed>>,
 
     // This tracks if we emitted some diagnostic for a given const value, so that
     // we will not subsequently issue an irrelevant lint for the same const
@@ -84,7 +84,7 @@ impl<'tcx> ConstToPat<'tcx> {
             span,
             infcx,
             param_env: pat_ctxt.param_env,
-            saw_const_match_error: Cell::new(false),
+            saw_const_match_error: Cell::new(None),
             saw_const_match_lint: Cell::new(false),
             behind_reference: Cell::new(false),
             treat_byte_string_as_slice: pat_ctxt
@@ -154,7 +154,7 @@ impl<'tcx> ConstToPat<'tcx> {
             }),
         };
 
-        if !self.saw_const_match_error.get() {
+        if self.saw_const_match_error.get().is_none() {
             // If we were able to successfully convert the const to some pat (possibly with some
             // lints, but no errors), double-check that all types in the const implement
             // `Structural` and `PartialEq`.
@@ -333,7 +333,7 @@ impl<'tcx> ConstToPat<'tcx> {
             // Backwards compatibility hack because we can't cause hard errors on these
             // types, so we compare them via `PartialEq::eq` at runtime.
             ty::Adt(..) if !self.type_marked_structural(ty) && self.behind_reference.get() => {
-                if !self.saw_const_match_error.get() && !self.saw_const_match_lint.get() {
+                if self.saw_const_match_error.get().is_none() && !self.saw_const_match_lint.get() {
                     self.saw_const_match_lint.set(true);
                     tcx.emit_spanned_lint(
                         lint::builtin::INDIRECT_STRUCTURAL_MATCH,
@@ -348,16 +348,16 @@ impl<'tcx> ConstToPat<'tcx> {
                 return Err(FallbackToOpaqueConst);
             }
             ty::FnDef(..) => {
-                self.saw_const_match_error.set(true);
                 let e = tcx.sess.emit_err(InvalidPattern { span, non_sm_ty: ty });
+                self.saw_const_match_error.set(Some(e));
                 // We errored. Signal that in the pattern, so that follow up errors can be silenced.
                 PatKind::Constant { value: mir::Const::Ty(ty::Const::new_error(tcx, e, ty)) }
             }
             ty::Adt(adt_def, _) if !self.type_marked_structural(ty) => {
                 debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, ty,);
-                self.saw_const_match_error.set(true);
                 let err = TypeNotStructural { span, non_sm_ty: ty };
                 let e = tcx.sess.emit_err(err);
+                self.saw_const_match_error.set(Some(e));
                 // We errored. Signal that in the pattern, so that follow up errors can be silenced.
                 PatKind::Constant { value: mir::Const::Ty(ty::Const::new_error(tcx, e, ty)) }
             }
@@ -419,7 +419,9 @@ impl<'tcx> ConstToPat<'tcx> {
                 // instead of a hard error.
                 ty::Adt(_, _) if !self.type_marked_structural(*pointee_ty) => {
                     if self.behind_reference.get() {
-                        if !self.saw_const_match_error.get() && !self.saw_const_match_lint.get() {
+                        if self.saw_const_match_error.get().is_none()
+                            && !self.saw_const_match_lint.get()
+                        {
                             self.saw_const_match_lint.set(true);
                             tcx.emit_spanned_lint(
                                 lint::builtin::INDIRECT_STRUCTURAL_MATCH,
@@ -430,15 +432,15 @@ impl<'tcx> ConstToPat<'tcx> {
                         }
                         return Err(FallbackToOpaqueConst);
                     } else {
-                        if self.saw_const_match_error.get() {
+                        if let Some(e) = self.saw_const_match_error.get() {
                             // We already errored. Signal that in the pattern, so that follow up errors can be silenced.
                             PatKind::Constant {
-                                value: mir::Const::Ty(ty::Const::new_misc_error(tcx, ty)),
+                                value: mir::Const::Ty(ty::Const::new_error(tcx, e, ty)),
                             }
                         } else {
-                            self.saw_const_match_error.set(true);
                             let err = TypeNotStructural { span, non_sm_ty: *pointee_ty };
                             let e = tcx.sess.emit_err(err);
+                            self.saw_const_match_error.set(Some(e));
                             // We errored. Signal that in the pattern, so that follow up errors can be silenced.
                             PatKind::Constant {
                                 value: mir::Const::Ty(ty::Const::new_error(tcx, e, ty)),
@@ -483,15 +485,15 @@ impl<'tcx> ConstToPat<'tcx> {
             }
             ty::FnPtr(..) | ty::RawPtr(..) => unreachable!(),
             _ => {
-                self.saw_const_match_error.set(true);
                 let err = InvalidPattern { span, non_sm_ty: ty };
                 let e = tcx.sess.emit_err(err);
+                self.saw_const_match_error.set(Some(e));
                 // We errored. Signal that in the pattern, so that follow up errors can be silenced.
                 PatKind::Constant { value: mir::Const::Ty(ty::Const::new_error(tcx, e, ty)) }
             }
         };
 
-        if !self.saw_const_match_error.get()
+        if self.saw_const_match_error.get().is_none()
             && !self.saw_const_match_lint.get()
             && mir_structural_match_violation
             // FIXME(#73448): Find a way to bring const qualification into parity with