@@ -870,6 +870,23 @@ pub fn find_repr_attrs(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
870
870
sym:: simd => Some ( ReprSimd ) ,
871
871
sym:: transparent => Some ( ReprTransparent ) ,
872
872
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
+ }
873
890
name => int_type_of_word ( name) . map ( ReprInt ) ,
874
891
} ;
875
892
@@ -891,53 +908,124 @@ pub fn find_repr_attrs(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
891
908
Ok ( literal) => acc. push ( ReprPacked ( literal) ) ,
892
909
Err ( message) => literal_error = Some ( message) ,
893
910
} ;
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 ( ) ;
894
922
}
895
923
if let Some ( literal_error) = literal_error {
896
924
struct_span_err ! (
897
925
diagnostic,
898
926
item. span( ) ,
899
927
E0589 ,
900
- "invalid `repr(align)` attribute: {}" ,
928
+ "invalid `repr({})` attribute: {}" ,
929
+ name. to_ident_string( ) ,
901
930
literal_error
902
931
)
903
932
. emit ( ) ;
904
933
}
905
934
} 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 ( ) ;
908
938
recognised = true ;
909
939
let mut err = struct_span_err ! (
910
940
diagnostic,
911
941
item. span( ) ,
912
942
E0693 ,
913
- "incorrect `repr(align)` attribute format"
943
+ "incorrect `repr({})` attribute format" ,
944
+ name,
914
945
) ;
915
946
match value. kind {
916
947
ast:: LitKind :: Int ( int, ast:: LitIntType :: Unsuffixed ) => {
917
948
err. span_suggestion (
918
949
item. span ( ) ,
919
950
"use parentheses instead" ,
920
- format ! ( "align ({})" , int) ,
951
+ format ! ( "{} ({})" , name , int) ,
921
952
Applicability :: MachineApplicable ,
922
953
) ;
923
954
}
924
955
ast:: LitKind :: Str ( s, _) => {
925
956
err. span_suggestion (
926
957
item. span ( ) ,
927
958
"use parentheses instead" ,
928
- format ! ( "align ({})" , s) ,
959
+ format ! ( "{} ({})" , name , s) ,
929
960
Applicability :: MachineApplicable ,
930
961
) ;
931
962
}
932
963
_ => { }
933
964
}
934
965
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 ( ) ;
935
1018
}
936
1019
}
937
1020
}
938
1021
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
+ }
941
1029
}
942
1030
}
943
1031
}
0 commit comments