@@ -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