@@ -7,7 +7,7 @@ use rustc_middle::mir;
77use rustc_middle:: thir:: { FieldPat , Pat , PatKind } ;
88use rustc_middle:: ty:: { self , Ty , TyCtxt , ValTree } ;
99use rustc_session:: lint;
10- use rustc_span:: Span ;
10+ use rustc_span:: { ErrorGuaranteed , Span } ;
1111use rustc_target:: abi:: { FieldIdx , VariantIdx } ;
1212use rustc_trait_selection:: traits:: query:: evaluate_obligation:: InferCtxtExt ;
1313use rustc_trait_selection:: traits:: { self , ObligationCause } ;
@@ -48,7 +48,7 @@ struct ConstToPat<'tcx> {
4848 // This tracks if we emitted some hard error for a given const value, so that
4949 // we will not subsequently issue an irrelevant lint for the same const
5050 // value.
51- saw_const_match_error : Cell < bool > ,
51+ saw_const_match_error : Cell < Option < ErrorGuaranteed > > ,
5252
5353 // This tracks if we emitted some diagnostic for a given const value, so that
5454 // we will not subsequently issue an irrelevant lint for the same const
@@ -84,7 +84,7 @@ impl<'tcx> ConstToPat<'tcx> {
8484 span,
8585 infcx,
8686 param_env : pat_ctxt. param_env ,
87- saw_const_match_error : Cell :: new ( false ) ,
87+ saw_const_match_error : Cell :: new ( None ) ,
8888 saw_const_match_lint : Cell :: new ( false ) ,
8989 behind_reference : Cell :: new ( false ) ,
9090 treat_byte_string_as_slice : pat_ctxt
@@ -154,7 +154,7 @@ impl<'tcx> ConstToPat<'tcx> {
154154 } ) ,
155155 } ;
156156
157- if ! self . saw_const_match_error . get ( ) {
157+ if self . saw_const_match_error . get ( ) . is_none ( ) {
158158 // If we were able to successfully convert the const to some pat (possibly with some
159159 // lints, but no errors), double-check that all types in the const implement
160160 // `Structural` and `PartialEq`.
@@ -333,7 +333,7 @@ impl<'tcx> ConstToPat<'tcx> {
333333 // Backwards compatibility hack because we can't cause hard errors on these
334334 // types, so we compare them via `PartialEq::eq` at runtime.
335335 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 ( ) {
337337 self . saw_const_match_lint . set ( true ) ;
338338 tcx. emit_spanned_lint (
339339 lint:: builtin:: INDIRECT_STRUCTURAL_MATCH ,
@@ -348,16 +348,16 @@ impl<'tcx> ConstToPat<'tcx> {
348348 return Err ( FallbackToOpaqueConst ) ;
349349 }
350350 ty:: FnDef ( ..) => {
351- self . saw_const_match_error . set ( true ) ;
352351 let e = tcx. sess . emit_err ( InvalidPattern { span, non_sm_ty : ty } ) ;
352+ self . saw_const_match_error . set ( Some ( e) ) ;
353353 // We errored. Signal that in the pattern, so that follow up errors can be silenced.
354354 PatKind :: Constant { value : mir:: Const :: Ty ( ty:: Const :: new_error ( tcx, e, ty) ) }
355355 }
356356 ty:: Adt ( adt_def, _) if !self . type_marked_structural ( ty) => {
357357 debug ! ( "adt_def {:?} has !type_marked_structural for cv.ty: {:?}" , adt_def, ty, ) ;
358- self . saw_const_match_error . set ( true ) ;
359358 let err = TypeNotStructural { span, non_sm_ty : ty } ;
360359 let e = tcx. sess . emit_err ( err) ;
360+ self . saw_const_match_error . set ( Some ( e) ) ;
361361 // We errored. Signal that in the pattern, so that follow up errors can be silenced.
362362 PatKind :: Constant { value : mir:: Const :: Ty ( ty:: Const :: new_error ( tcx, e, ty) ) }
363363 }
@@ -419,7 +419,9 @@ impl<'tcx> ConstToPat<'tcx> {
419419 // instead of a hard error.
420420 ty:: Adt ( _, _) if !self . type_marked_structural ( * pointee_ty) => {
421421 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+ {
423425 self . saw_const_match_lint . set ( true ) ;
424426 tcx. emit_spanned_lint (
425427 lint:: builtin:: INDIRECT_STRUCTURAL_MATCH ,
@@ -430,15 +432,15 @@ impl<'tcx> ConstToPat<'tcx> {
430432 }
431433 return Err ( FallbackToOpaqueConst ) ;
432434 } else {
433- if self . saw_const_match_error . get ( ) {
435+ if let Some ( e ) = self . saw_const_match_error . get ( ) {
434436 // We already errored. Signal that in the pattern, so that follow up errors can be silenced.
435437 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) ) ,
437439 }
438440 } else {
439- self . saw_const_match_error . set ( true ) ;
440441 let err = TypeNotStructural { span, non_sm_ty : * pointee_ty } ;
441442 let e = tcx. sess . emit_err ( err) ;
443+ self . saw_const_match_error . set ( Some ( e) ) ;
442444 // We errored. Signal that in the pattern, so that follow up errors can be silenced.
443445 PatKind :: Constant {
444446 value : mir:: Const :: Ty ( ty:: Const :: new_error ( tcx, e, ty) ) ,
@@ -483,15 +485,15 @@ impl<'tcx> ConstToPat<'tcx> {
483485 }
484486 ty:: FnPtr ( ..) | ty:: RawPtr ( ..) => unreachable ! ( ) ,
485487 _ => {
486- self . saw_const_match_error . set ( true ) ;
487488 let err = InvalidPattern { span, non_sm_ty : ty } ;
488489 let e = tcx. sess . emit_err ( err) ;
490+ self . saw_const_match_error . set ( Some ( e) ) ;
489491 // We errored. Signal that in the pattern, so that follow up errors can be silenced.
490492 PatKind :: Constant { value : mir:: Const :: Ty ( ty:: Const :: new_error ( tcx, e, ty) ) }
491493 }
492494 } ;
493495
494- if ! self . saw_const_match_error . get ( )
496+ if self . saw_const_match_error . get ( ) . is_none ( )
495497 && !self . saw_const_match_lint . get ( )
496498 && mir_structural_match_violation
497499 // FIXME(#73448): Find a way to bring const qualification into parity with
0 commit comments