@@ -870,6 +870,23 @@ pub fn find_repr_attrs(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
870870 sym:: simd => Some ( ReprSimd ) ,
871871 sym:: transparent => Some ( ReprTransparent ) ,
872872 sym:: no_niche => Some ( ReprNoNiche ) ,
873+ sym:: align => {
874+ let mut err = struct_span_err ! (
875+ diagnostic,
876+ item. span( ) ,
877+ E0589 ,
878+ "invalid `repr(align)` attribute: `align` needs an argument"
879+ ) ;
880+ err. span_suggestion (
881+ item. span ( ) ,
882+ "supply an argument here" ,
883+ "align(...)" . to_string ( ) ,
884+ Applicability :: HasPlaceholders ,
885+ ) ;
886+ err. emit ( ) ;
887+ recognised = true ;
888+ None
889+ }
873890 name => int_type_of_word ( name) . map ( ReprInt ) ,
874891 } ;
875892
@@ -891,53 +908,124 @@ pub fn find_repr_attrs(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
891908 Ok ( literal) => acc. push ( ReprPacked ( literal) ) ,
892909 Err ( message) => literal_error = Some ( message) ,
893910 } ;
911+ } else if matches ! ( name, sym:: C | sym:: simd | sym:: transparent | sym:: no_niche)
912+ || int_type_of_word ( name) . is_some ( )
913+ {
914+ recognised = true ;
915+ struct_span_err ! (
916+ diagnostic,
917+ item. span( ) ,
918+ E0552 ,
919+ "invalid representation hint: `{}` does not take a parenthesized argument list" ,
920+ name. to_ident_string( ) ,
921+ ) . emit ( ) ;
894922 }
895923 if let Some ( literal_error) = literal_error {
896924 struct_span_err ! (
897925 diagnostic,
898926 item. span( ) ,
899927 E0589 ,
900- "invalid `repr(align)` attribute: {}" ,
928+ "invalid `repr({})` attribute: {}" ,
929+ name. to_ident_string( ) ,
901930 literal_error
902931 )
903932 . emit ( ) ;
904933 }
905934 } else if let Some ( meta_item) = item. meta_item ( ) {
906- if meta_item. has_name ( sym:: align) {
907- if let MetaItemKind :: NameValue ( ref value) = meta_item. kind {
935+ if let MetaItemKind :: NameValue ( ref value) = meta_item. kind {
936+ if meta_item. has_name ( sym:: align) || meta_item. has_name ( sym:: packed) {
937+ let name = meta_item. name_or_empty ( ) . to_ident_string ( ) ;
908938 recognised = true ;
909939 let mut err = struct_span_err ! (
910940 diagnostic,
911941 item. span( ) ,
912942 E0693 ,
913- "incorrect `repr(align)` attribute format"
943+ "incorrect `repr({})` attribute format" ,
944+ name,
914945 ) ;
915946 match value. kind {
916947 ast:: LitKind :: Int ( int, ast:: LitIntType :: Unsuffixed ) => {
917948 err. span_suggestion (
918949 item. span ( ) ,
919950 "use parentheses instead" ,
920- format ! ( "align ({})" , int) ,
951+ format ! ( "{} ({})" , name , int) ,
921952 Applicability :: MachineApplicable ,
922953 ) ;
923954 }
924955 ast:: LitKind :: Str ( s, _) => {
925956 err. span_suggestion (
926957 item. span ( ) ,
927958 "use parentheses instead" ,
928- format ! ( "align ({})" , s) ,
959+ format ! ( "{} ({})" , name , s) ,
929960 Applicability :: MachineApplicable ,
930961 ) ;
931962 }
932963 _ => { }
933964 }
934965 err. emit ( ) ;
966+ } else {
967+ if matches ! (
968+ meta_item. name_or_empty( ) ,
969+ sym:: C | sym:: simd | sym:: transparent | sym:: no_niche
970+ ) || int_type_of_word ( meta_item. name_or_empty ( ) ) . is_some ( )
971+ {
972+ recognised = true ;
973+ struct_span_err ! (
974+ diagnostic,
975+ meta_item. span,
976+ E0552 ,
977+ "invalid representation hint: `{}` does not take a value" ,
978+ meta_item. name_or_empty( ) . to_ident_string( ) ,
979+ )
980+ . emit ( ) ;
981+ }
982+ }
983+ } else if let MetaItemKind :: List ( _) = meta_item. kind {
984+ if meta_item. has_name ( sym:: align) {
985+ recognised = true ;
986+ struct_span_err ! (
987+ diagnostic,
988+ meta_item. span,
989+ E0693 ,
990+ "incorrect `repr(align)` attribute format: \
991+ `align` takes exactly one argument in parentheses"
992+ )
993+ . emit ( ) ;
994+ } else if meta_item. has_name ( sym:: packed) {
995+ recognised = true ;
996+ struct_span_err ! (
997+ diagnostic,
998+ meta_item. span,
999+ E0552 ,
1000+ "incorrect `repr(packed)` attribute format: \
1001+ `packed` takes exactly one parenthesized argument, \
1002+ or no parentheses at all"
1003+ )
1004+ . emit ( ) ;
1005+ } else if matches ! (
1006+ meta_item. name_or_empty( ) ,
1007+ sym:: C | sym:: simd | sym:: transparent | sym:: no_niche
1008+ ) || int_type_of_word ( meta_item. name_or_empty ( ) ) . is_some ( )
1009+ {
1010+ recognised = true ;
1011+ struct_span_err ! (
1012+ diagnostic,
1013+ meta_item. span,
1014+ E0552 ,
1015+ "invalid representation hint: `{}` does not take a parenthesized argument list" ,
1016+ meta_item. name_or_empty( ) . to_ident_string( ) ,
1017+ ) . emit ( ) ;
9351018 }
9361019 }
9371020 }
9381021 if !recognised {
939- // Not a word we recognize
940- diagnostic. delay_span_bug ( item. span ( ) , "unrecognized representation hint" ) ;
1022+ // Not a word we recognize. This will be caught and reported by
1023+ // the `check_mod_attrs` pass, but this pass doesn't always run
1024+ // (e.g. if we only pretty-print the source), so we have to gate
1025+ // the `delay_span_bug` call as follows:
1026+ if sess. opts . pretty . map_or ( true , |pp| pp. needs_analysis ( ) ) {
1027+ diagnostic. delay_span_bug ( item. span ( ) , "unrecognized representation hint" ) ;
1028+ }
9411029 }
9421030 }
9431031 }
0 commit comments