@@ -673,6 +673,75 @@ impl EarlyLintPass for AnonymousParameters {
673
673
}
674
674
}
675
675
676
+ /// Checks for incorrect use use of `repr` attributes.
677
+ #[ derive( Clone ) ]
678
+ pub struct BadRepr ;
679
+
680
+ impl LintPass for BadRepr {
681
+ fn get_lints ( & self ) -> LintArray {
682
+ lint_array ! ( )
683
+ }
684
+ }
685
+
686
+ impl EarlyLintPass for BadRepr {
687
+ fn check_attribute ( & mut self , cx : & EarlyContext , attr : & ast:: Attribute ) {
688
+ if attr. name ( ) == "repr" {
689
+ let list = attr. meta_item_list ( ) ;
690
+
691
+ // Emit warnings with `repr` either has a literal assignment (`#[repr = "C"]`) or
692
+ // no hints (``#[repr]`)
693
+ let has_hints = list. as_ref ( ) . map ( |ref list| !list. is_empty ( ) ) . unwrap_or ( false ) ;
694
+ if !has_hints {
695
+ let mut suggested = false ;
696
+ let mut warn = if let Some ( ref lit) = attr. value_str ( ) {
697
+ // avoid warning about empty `repr` on `#[repr = "foo"]`
698
+ let sp = match format ! ( "{}" , lit) . as_ref ( ) {
699
+ "C" | "packed" | "rust" | "u*" | "i*" => {
700
+ let lo = attr. span . lo ( ) + BytePos ( 2 ) ;
701
+ let hi = attr. span . hi ( ) - BytePos ( 1 ) ;
702
+ suggested = true ;
703
+ attr. span . with_lo ( lo) . with_hi ( hi)
704
+ }
705
+ _ => attr. span , // the literal wasn't a valid `repr` arg
706
+ } ;
707
+ let mut warn = cx. struct_span_lint (
708
+ BAD_REPR ,
709
+ sp,
710
+ "`repr` attribute isn't configurable with a literal" ,
711
+ ) ;
712
+ if suggested {
713
+ // if the literal could have been a valid `repr` arg,
714
+ // suggest the correct syntax
715
+ warn. span_suggestion (
716
+ sp,
717
+ "give `repr` a hint" ,
718
+ format ! ( "repr({})" , lit) ,
719
+ ) ;
720
+ } else {
721
+ warn. span_label ( attr. span , "needs a hint" ) ;
722
+ }
723
+ warn
724
+ } else {
725
+ let mut warn = cx. struct_span_lint (
726
+ BAD_REPR ,
727
+ attr. span ,
728
+ "`repr` attribute must have a hint" ,
729
+ ) ;
730
+ warn. span_label ( attr. span , "needs a hint" ) ;
731
+ warn
732
+ } ;
733
+ if !suggested {
734
+ warn. help ( "valid hints include `#[repr(C)]`, `#[repr(packed)]` and \
735
+ `#[repr(rust)]`") ;
736
+ warn. note ( "for more information, visit \
737
+ <https://doc.rust-lang.org/nomicon/other-reprs.html>") ;
738
+ }
739
+ warn. emit ( ) ;
740
+ }
741
+ }
742
+ }
743
+ }
744
+
676
745
/// Checks for use of attributes which have been deprecated.
677
746
#[ derive( Clone ) ]
678
747
pub struct DeprecatedAttr {
0 commit comments