Remember the ErrorReported used to silence follow up errors instead of recreating it with delay_span_bug

This commit is contained in:
Oli Scherer 2023-09-28 15:59:53 +00:00
parent e83467c3b8
commit eca786cd14

View File

@ -7,7 +7,7 @@
use rustc_middle::thir::{FieldPat, Pat, PatKind}; use rustc_middle::thir::{FieldPat, Pat, PatKind};
use rustc_middle::ty::{self, Ty, TyCtxt, ValTree}; use rustc_middle::ty::{self, Ty, TyCtxt, ValTree};
use rustc_session::lint; use rustc_session::lint;
use rustc_span::Span; use rustc_span::{ErrorGuaranteed, Span};
use rustc_target::abi::{FieldIdx, VariantIdx}; use rustc_target::abi::{FieldIdx, VariantIdx};
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
use rustc_trait_selection::traits::{self, ObligationCause}; 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 // 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 // we will not subsequently issue an irrelevant lint for the same const
// value. // 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 // 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 // we will not subsequently issue an irrelevant lint for the same const
@ -84,7 +84,7 @@ fn new(
span, span,
infcx, infcx,
param_env: pat_ctxt.param_env, 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), saw_const_match_lint: Cell::new(false),
behind_reference: Cell::new(false), behind_reference: Cell::new(false),
treat_byte_string_as_slice: pat_ctxt 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 // 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 // lints, but no errors), double-check that all types in the const implement
// `Structural` and `PartialEq`. // `Structural` and `PartialEq`.
@ -333,7 +333,7 @@ fn recur(
// Backwards compatibility hack because we can't cause hard errors on these // Backwards compatibility hack because we can't cause hard errors on these
// types, so we compare them via `PartialEq::eq` at runtime. // types, so we compare them via `PartialEq::eq` at runtime.
ty::Adt(..) if !self.type_marked_structural(ty) && self.behind_reference.get() => { 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); self.saw_const_match_lint.set(true);
tcx.emit_spanned_lint( tcx.emit_spanned_lint(
lint::builtin::INDIRECT_STRUCTURAL_MATCH, lint::builtin::INDIRECT_STRUCTURAL_MATCH,
@ -348,16 +348,16 @@ fn recur(
return Err(FallbackToOpaqueConst); return Err(FallbackToOpaqueConst);
} }
ty::FnDef(..) => { ty::FnDef(..) => {
self.saw_const_match_error.set(true);
let e = tcx.sess.emit_err(InvalidPattern { span, non_sm_ty: ty }); 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. // 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)) } PatKind::Constant { value: mir::Const::Ty(ty::Const::new_error(tcx, e, ty)) }
} }
ty::Adt(adt_def, _) if !self.type_marked_structural(ty) => { ty::Adt(adt_def, _) if !self.type_marked_structural(ty) => {
debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, 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 err = TypeNotStructural { span, non_sm_ty: ty };
let e = tcx.sess.emit_err(err); 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. // 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)) } PatKind::Constant { value: mir::Const::Ty(ty::Const::new_error(tcx, e, ty)) }
} }
@ -419,7 +419,9 @@ fn recur(
// instead of a hard error. // instead of a hard error.
ty::Adt(_, _) if !self.type_marked_structural(*pointee_ty) => { ty::Adt(_, _) if !self.type_marked_structural(*pointee_ty) => {
if self.behind_reference.get() { 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); self.saw_const_match_lint.set(true);
tcx.emit_spanned_lint( tcx.emit_spanned_lint(
lint::builtin::INDIRECT_STRUCTURAL_MATCH, lint::builtin::INDIRECT_STRUCTURAL_MATCH,
@ -430,15 +432,15 @@ fn recur(
} }
return Err(FallbackToOpaqueConst); return Err(FallbackToOpaqueConst);
} else { } 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. // We already errored. Signal that in the pattern, so that follow up errors can be silenced.
PatKind::Constant { 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 { } else {
self.saw_const_match_error.set(true);
let err = TypeNotStructural { span, non_sm_ty: *pointee_ty }; let err = TypeNotStructural { span, non_sm_ty: *pointee_ty };
let e = tcx.sess.emit_err(err); 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. // We errored. Signal that in the pattern, so that follow up errors can be silenced.
PatKind::Constant { PatKind::Constant {
value: mir::Const::Ty(ty::Const::new_error(tcx, e, ty)), value: mir::Const::Ty(ty::Const::new_error(tcx, e, ty)),
@ -483,15 +485,15 @@ fn recur(
} }
ty::FnPtr(..) | ty::RawPtr(..) => unreachable!(), ty::FnPtr(..) | ty::RawPtr(..) => unreachable!(),
_ => { _ => {
self.saw_const_match_error.set(true);
let err = InvalidPattern { span, non_sm_ty: ty }; let err = InvalidPattern { span, non_sm_ty: ty };
let e = tcx.sess.emit_err(err); 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. // 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)) } 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() && !self.saw_const_match_lint.get()
&& mir_structural_match_violation && mir_structural_match_violation
// FIXME(#73448): Find a way to bring const qualification into parity with // FIXME(#73448): Find a way to bring const qualification into parity with