@@ -104,7 +104,7 @@ impl CheckAttrVisitor<'tcx> {
104
104
return ;
105
105
}
106
106
107
- if matches ! ( target, Target :: Fn | Target :: Method ( _) | Target :: ForeignFn ) {
107
+ if matches ! ( target, Target :: Closure | Target :: Fn | Target :: Method ( _) | Target :: ForeignFn ) {
108
108
self . tcx . ensure ( ) . codegen_fn_attrs ( self . tcx . hir ( ) . local_def_id ( hir_id) ) ;
109
109
}
110
110
@@ -195,7 +195,7 @@ impl CheckAttrVisitor<'tcx> {
195
195
/// Checks if the `#[non_exhaustive]` attribute on an `item` is valid. Returns `true` if valid.
196
196
fn check_non_exhaustive ( & self , attr : & Attribute , span : & Span , target : Target ) -> bool {
197
197
match target {
198
- Target :: Struct | Target :: Enum => true ,
198
+ Target :: Struct | Target :: Enum | Target :: Variant => true ,
199
199
_ => {
200
200
struct_span_err ! (
201
201
self . tcx. sess,
@@ -587,6 +587,9 @@ impl CheckAttrVisitor<'tcx> {
587
587
588
588
for hint in & hints {
589
589
let ( article, allowed_targets) = match hint. name_or_empty ( ) {
590
+ _ if !matches ! ( target, Target :: Struct | Target :: Enum | Target :: Union ) => {
591
+ ( "a" , "struct, enum, or union" )
592
+ }
590
593
name @ sym:: C | name @ sym:: align => {
591
594
is_c |= name == sym:: C ;
592
595
match target {
@@ -652,12 +655,16 @@ impl CheckAttrVisitor<'tcx> {
652
655
}
653
656
_ => continue ,
654
657
} ;
655
- self . emit_repr_error (
658
+
659
+ struct_span_err ! (
660
+ self . tcx. sess,
656
661
hint. span( ) ,
657
- * span ,
658
- & format ! ( "attribute should be applied to {}", allowed_targets ) ,
659
- & format ! ( "not {} {}" , article, allowed_targets) ,
662
+ E0517 ,
663
+ " {}",
664
+ & format!( "attribute should be applied to {} {}" , article, allowed_targets)
660
665
)
666
+ . span_label ( * span, & format ! ( "not {} {}" , article, allowed_targets) )
667
+ . emit ( ) ;
661
668
}
662
669
663
670
// Just point at all repr hints if there are any incompatibilities.
@@ -703,56 +710,6 @@ impl CheckAttrVisitor<'tcx> {
703
710
}
704
711
}
705
712
706
- fn emit_repr_error (
707
- & self ,
708
- hint_span : Span ,
709
- label_span : Span ,
710
- hint_message : & str ,
711
- label_message : & str ,
712
- ) {
713
- struct_span_err ! ( self . tcx. sess, hint_span, E0517 , "{}" , hint_message)
714
- . span_label ( label_span, label_message)
715
- . emit ( ) ;
716
- }
717
-
718
- fn check_stmt_attributes ( & self , stmt : & hir:: Stmt < ' _ > ) {
719
- // When checking statements ignore expressions, they will be checked later
720
- if let hir:: StmtKind :: Local ( ref l) = stmt. kind {
721
- self . check_attributes ( l. hir_id , & l. attrs , & stmt. span , Target :: Statement , None ) ;
722
- for attr in l. attrs . iter ( ) {
723
- if self . tcx . sess . check_name ( attr, sym:: repr) {
724
- self . emit_repr_error (
725
- attr. span ,
726
- stmt. span ,
727
- "attribute should not be applied to a statement" ,
728
- "not a struct, enum, or union" ,
729
- ) ;
730
- }
731
- }
732
- }
733
- }
734
-
735
- fn check_expr_attributes ( & self , expr : & hir:: Expr < ' _ > ) {
736
- let target = match expr. kind {
737
- hir:: ExprKind :: Closure ( ..) => Target :: Closure ,
738
- _ => Target :: Expression ,
739
- } ;
740
- self . check_attributes ( expr. hir_id , & expr. attrs , & expr. span , target, None ) ;
741
- for attr in expr. attrs . iter ( ) {
742
- if self . tcx . sess . check_name ( attr, sym:: repr) {
743
- self . emit_repr_error (
744
- attr. span ,
745
- expr. span ,
746
- "attribute should not be applied to an expression" ,
747
- "not defining a struct, enum, or union" ,
748
- ) ;
749
- }
750
- }
751
- if target == Target :: Closure {
752
- self . tcx . ensure ( ) . codegen_fn_attrs ( self . tcx . hir ( ) . local_def_id ( expr. hir_id ) ) ;
753
- }
754
- }
755
-
756
713
fn check_used ( & self , attrs : & ' hir [ Attribute ] , target : Target ) {
757
714
for attr in attrs {
758
715
if self . tcx . sess . check_name ( attr, sym:: used) && target != Target :: Static {
@@ -808,14 +765,32 @@ impl Visitor<'tcx> for CheckAttrVisitor<'tcx> {
808
765
}
809
766
810
767
fn visit_stmt ( & mut self , stmt : & ' tcx hir:: Stmt < ' tcx > ) {
811
- self . check_stmt_attributes ( stmt) ;
768
+ // When checking statements ignore expressions, they will be checked later.
769
+ if let hir:: StmtKind :: Local ( ref l) = stmt. kind {
770
+ self . check_attributes ( l. hir_id , & l. attrs , & stmt. span , Target :: Statement , None ) ;
771
+ }
812
772
intravisit:: walk_stmt ( self , stmt)
813
773
}
814
774
815
775
fn visit_expr ( & mut self , expr : & ' tcx hir:: Expr < ' tcx > ) {
816
- self . check_expr_attributes ( expr) ;
776
+ let target = match expr. kind {
777
+ hir:: ExprKind :: Closure ( ..) => Target :: Closure ,
778
+ _ => Target :: Expression ,
779
+ } ;
780
+
781
+ self . check_attributes ( expr. hir_id , & expr. attrs , & expr. span , target, None ) ;
817
782
intravisit:: walk_expr ( self , expr)
818
783
}
784
+
785
+ fn visit_variant (
786
+ & mut self ,
787
+ variant : & ' tcx hir:: Variant < ' tcx > ,
788
+ generics : & ' tcx hir:: Generics < ' tcx > ,
789
+ item_id : HirId ,
790
+ ) {
791
+ self . check_attributes ( variant. id , variant. attrs , & variant. span , Target :: Variant , None ) ;
792
+ intravisit:: walk_variant ( self , variant, generics, item_id)
793
+ }
819
794
}
820
795
821
796
fn is_c_like_enum ( item : & Item < ' _ > ) -> bool {
0 commit comments