@@ -7,7 +7,7 @@ use rustc_middle::mir;
7
7
use rustc_middle::thir::{FieldPat, Pat, PatKind};
8
8
use rustc_middle::ty::{self, Ty, TyCtxt, ValTree};
9
9
use rustc_session::lint;
10
- use rustc_span::Span;
10
+ use rustc_span::{ErrorGuaranteed, Span} ;
11
11
use rustc_target::abi::{FieldIdx, VariantIdx};
12
12
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
13
13
use rustc_trait_selection::traits::{self, ObligationCause};
@@ -48,7 +48,7 @@ struct ConstToPat<'tcx> {
48
48
// This tracks if we emitted some hard error for a given const value, so that
49
49
// we will not subsequently issue an irrelevant lint for the same const
50
50
// value.
51
- saw_const_match_error: Cell<bool >,
51
+ saw_const_match_error: Cell<Option<ErrorGuaranteed> >,
52
52
53
53
// This tracks if we emitted some diagnostic for a given const value, so that
54
54
// we will not subsequently issue an irrelevant lint for the same const
@@ -84,7 +84,7 @@ impl<'tcx> ConstToPat<'tcx> {
84
84
span,
85
85
infcx,
86
86
param_env: pat_ctxt.param_env,
87
- saw_const_match_error: Cell::new(false ),
87
+ saw_const_match_error: Cell::new(None ),
88
88
saw_const_match_lint: Cell::new(false),
89
89
behind_reference: Cell::new(false),
90
90
treat_byte_string_as_slice: pat_ctxt
@@ -154,7 +154,7 @@ impl<'tcx> ConstToPat<'tcx> {
154
154
}),
155
155
};
156
156
157
- if ! self.saw_const_match_error.get() {
157
+ if self.saw_const_match_error.get().is_none () {
158
158
// If we were able to successfully convert the const to some pat (possibly with some
159
159
// lints, but no errors), double-check that all types in the const implement
160
160
// `Structural` and `PartialEq`.
@@ -333,7 +333,7 @@ impl<'tcx> ConstToPat<'tcx> {
333
333
// Backwards compatibility hack because we can't cause hard errors on these
334
334
// types, so we compare them via `PartialEq::eq` at runtime.
335
335
ty::Adt(..) if !self.type_marked_structural(ty) && self.behind_reference.get() => {
336
- if ! self.saw_const_match_error.get() && !self.saw_const_match_lint.get() {
336
+ if self.saw_const_match_error.get().is_none () && !self.saw_const_match_lint.get() {
337
337
self.saw_const_match_lint.set(true);
338
338
tcx.emit_spanned_lint(
339
339
lint::builtin::INDIRECT_STRUCTURAL_MATCH,
@@ -348,16 +348,16 @@ impl<'tcx> ConstToPat<'tcx> {
348
348
return Err(FallbackToOpaqueConst);
349
349
}
350
350
ty::FnDef(..) => {
351
- self.saw_const_match_error.set(true);
352
351
let e = tcx.sess.emit_err(InvalidPattern { span, non_sm_ty: ty });
352
+ self.saw_const_match_error.set(Some(e));
353
353
// We errored. Signal that in the pattern, so that follow up errors can be silenced.
354
354
PatKind::Constant { value: mir::Const::Ty(ty::Const::new_error(tcx, e, ty)) }
355
355
}
356
356
ty::Adt(adt_def, _) if !self.type_marked_structural(ty) => {
357
357
debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, ty,);
358
- self.saw_const_match_error.set(true);
359
358
let err = TypeNotStructural { span, non_sm_ty: ty };
360
359
let e = tcx.sess.emit_err(err);
360
+ self.saw_const_match_error.set(Some(e));
361
361
// We errored. Signal that in the pattern, so that follow up errors can be silenced.
362
362
PatKind::Constant { value: mir::Const::Ty(ty::Const::new_error(tcx, e, ty)) }
363
363
}
@@ -419,7 +419,9 @@ impl<'tcx> ConstToPat<'tcx> {
419
419
// instead of a hard error.
420
420
ty::Adt(_, _) if !self.type_marked_structural(*pointee_ty) => {
421
421
if self.behind_reference.get() {
422
- if !self.saw_const_match_error.get() && !self.saw_const_match_lint.get() {
422
+ if self.saw_const_match_error.get().is_none()
423
+ && !self.saw_const_match_lint.get()
424
+ {
423
425
self.saw_const_match_lint.set(true);
424
426
tcx.emit_spanned_lint(
425
427
lint::builtin::INDIRECT_STRUCTURAL_MATCH,
@@ -430,15 +432,15 @@ impl<'tcx> ConstToPat<'tcx> {
430
432
}
431
433
return Err(FallbackToOpaqueConst);
432
434
} else {
433
- if self.saw_const_match_error.get() {
435
+ if let Some(e) = self.saw_const_match_error.get() {
434
436
// We already errored. Signal that in the pattern, so that follow up errors can be silenced.
435
437
PatKind::Constant {
436
- value: mir::Const::Ty(ty::Const::new_misc_error (tcx, ty)),
438
+ value: mir::Const::Ty(ty::Const::new_error (tcx, e , ty)),
437
439
}
438
440
} else {
439
- self.saw_const_match_error.set(true);
440
441
let err = TypeNotStructural { span, non_sm_ty: *pointee_ty };
441
442
let e = tcx.sess.emit_err(err);
443
+ self.saw_const_match_error.set(Some(e));
442
444
// We errored. Signal that in the pattern, so that follow up errors can be silenced.
443
445
PatKind::Constant {
444
446
value: mir::Const::Ty(ty::Const::new_error(tcx, e, ty)),
@@ -483,15 +485,15 @@ impl<'tcx> ConstToPat<'tcx> {
483
485
}
484
486
ty::FnPtr(..) | ty::RawPtr(..) => unreachable!(),
485
487
_ => {
486
- self.saw_const_match_error.set(true);
487
488
let err = InvalidPattern { span, non_sm_ty: ty };
488
489
let e = tcx.sess.emit_err(err);
490
+ self.saw_const_match_error.set(Some(e));
489
491
// We errored. Signal that in the pattern, so that follow up errors can be silenced.
490
492
PatKind::Constant { value: mir::Const::Ty(ty::Const::new_error(tcx, e, ty)) }
491
493
}
492
494
};
493
495
494
- if ! self.saw_const_match_error.get()
496
+ if self.saw_const_match_error.get().is_none ()
495
497
&& !self.saw_const_match_lint.get()
496
498
&& mir_structural_match_violation
497
499
// FIXME(#73448): Find a way to bring const qualification into parity with
0 commit comments