@@ -124,7 +124,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
124124 [ sym:: coverage, ..] => self . check_coverage ( attr, span, target) ,
125125 [ sym:: optimize, ..] => self . check_optimize ( hir_id, attr, span, target) ,
126126 [ sym:: no_sanitize, ..] => self . check_no_sanitize ( attr, span, target) ,
127- [ sym:: non_exhaustive, ..] => self . check_non_exhaustive ( hir_id, attr, span, target) ,
127+ [ sym:: non_exhaustive, ..] => self . check_non_exhaustive ( hir_id, attr, span, target, item ) ,
128128 [ sym:: marker, ..] => self . check_marker ( hir_id, attr, span, target) ,
129129 [ sym:: target_feature, ..] => {
130130 self . check_target_feature ( hir_id, attr, span, target, attrs)
@@ -685,9 +685,30 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
685685 }
686686
687687 /// Checks if the `#[non_exhaustive]` attribute on an `item` is valid.
688- fn check_non_exhaustive ( & self , hir_id : HirId , attr : & Attribute , span : Span , target : Target ) {
688+ fn check_non_exhaustive (
689+ & self ,
690+ hir_id : HirId ,
691+ attr : & Attribute ,
692+ span : Span ,
693+ target : Target ,
694+ item : Option < ItemLike < ' _ > > ,
695+ ) {
689696 match target {
690- Target :: Struct | Target :: Enum | Target :: Variant => { }
697+ Target :: Struct => {
698+ if let Some ( ItemLike :: Item ( hir:: Item {
699+ kind : hir:: ItemKind :: Struct ( hir:: VariantData :: Struct { fields, .. } , _) ,
700+ ..
701+ } ) ) = item
702+ && !fields. is_empty ( )
703+ && fields. iter ( ) . any ( |f| f. default . is_some ( ) )
704+ {
705+ self . dcx ( ) . emit_err ( errors:: NonExhaustiveWithDefaultFieldValues {
706+ attr_span : attr. span ,
707+ defn_span : span,
708+ } ) ;
709+ }
710+ }
711+ Target :: Enum | Target :: Variant => { }
691712 // FIXME(#80564): We permit struct fields, match arms and macro defs to have an
692713 // `#[non_exhaustive]` attribute with just a lint, because we previously
693714 // erroneously allowed it and some crates used it accidentally, to be compatible
0 commit comments