@@ -66,6 +66,8 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
6666 for attr in & item. attrs {
6767 if attr. check_name ( "inline" ) {
6868 self . check_inline ( attr, & item. span , target)
69+ } else if attr. check_name ( "non_exhaustive" ) {
70+ self . check_non_exhaustive ( attr, item, target)
6971 } else if attr. check_name ( "wasm_import_module" ) {
7072 has_wasm_import_module = true ;
7173 if attr. value_str ( ) . is_none ( ) {
@@ -113,6 +115,31 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
113115 }
114116 }
115117
118+ /// Check if the `#[non_exhaustive]` attribute on an `item` is valid.
119+ fn check_non_exhaustive ( & self , attr : & hir:: Attribute , item : & hir:: Item , target : Target ) {
120+ match target {
121+ Target :: Struct | Target :: Enum => { /* Valid */ } ,
122+ _ => {
123+ struct_span_err ! ( self . tcx. sess,
124+ attr. span,
125+ E0910 ,
126+ "attribute can only be applied to a struct or enum" )
127+ . span_label ( item. span , "not a struct or enum" )
128+ . emit ( ) ;
129+ return ;
130+ }
131+ }
132+
133+ if attr. meta_item_list ( ) . is_some ( ) || attr. value_str ( ) . is_some ( ) {
134+ struct_span_err ! ( self . tcx. sess,
135+ attr. span,
136+ E0911 ,
137+ "attribute should be empty" )
138+ . span_label ( item. span , "not empty" )
139+ . emit ( ) ;
140+ }
141+ }
142+
116143 /// Check if the `#[repr]` attributes on `item` are valid.
117144 fn check_repr ( & self , item : & hir:: Item , target : Target ) {
118145 // Extract the names of all repr hints, e.g., [foo, bar, align] for:
0 commit comments