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::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, + saw_const_match_error: Cell>, // 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 @@ fn new( 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 @@ fn to_pat( }), }; - 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 @@ fn recur( // 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 @@ fn recur( 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 @@ fn recur( // 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 @@ fn recur( } 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 @@ fn recur( } 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