11//! Meta-syntax validation logic of attributes for post-expansion.
22
3+ use crate :: parse_in;
4+
35use rustc_errors:: { PResult , Applicability } ;
46use rustc_feature:: { AttributeTemplate , BUILTIN_ATTRIBUTE_MAP } ;
5- use syntax:: ast:: { self , Attribute , AttrKind , Ident , MacArgs , MetaItem , MetaItemKind } ;
7+ use syntax:: ast:: { self , Attribute , AttrKind , Ident , MacArgs , MacDelimiter , MetaItem , MetaItemKind } ;
68use syntax:: attr:: mk_name_value_item_str;
79use syntax:: early_buffered_lints:: ILL_FORMED_ATTRIBUTE_INPUT ;
10+ use syntax:: tokenstream:: DelimSpan ;
811use syntax:: sess:: ParseSess ;
912use syntax_pos:: { Symbol , sym} ;
1013
@@ -27,16 +30,45 @@ pub fn check_meta(sess: &ParseSess, attr: &Attribute) {
2730pub fn parse_meta < ' a > ( sess : & ' a ParseSess , attr : & Attribute ) -> PResult < ' a , MetaItem > {
2831 Ok ( match attr. kind {
2932 AttrKind :: Normal ( ref item) => MetaItem {
30- path : item. path . clone ( ) ,
31- kind : super :: parse_in_attr ( sess, attr, |p| p. parse_meta_item_kind ( ) ) ?,
3233 span : attr. span ,
34+ path : item. path . clone ( ) ,
35+ kind : match & attr. get_normal_item ( ) . args {
36+ MacArgs :: Empty => MetaItemKind :: Word ,
37+ MacArgs :: Eq ( _, t) => {
38+ let v = parse_in ( sess, t. clone ( ) , "name value" , |p| p. parse_unsuffixed_lit ( ) ) ?;
39+ MetaItemKind :: NameValue ( v)
40+ }
41+ MacArgs :: Delimited ( dspan, delim, t) => {
42+ check_meta_bad_delim ( sess, * dspan, * delim, "wrong meta list delimiters" ) ;
43+ let nmis = parse_in ( sess, t. clone ( ) , "meta list" , |p| p. parse_meta_seq_top ( ) ) ?;
44+ MetaItemKind :: List ( nmis)
45+ }
46+ }
3347 } ,
3448 AttrKind :: DocComment ( comment) => {
3549 mk_name_value_item_str ( Ident :: new ( sym:: doc, attr. span ) , comment, attr. span )
3650 }
3751 } )
3852}
3953
54+ crate fn check_meta_bad_delim ( sess : & ParseSess , span : DelimSpan , delim : MacDelimiter , msg : & str ) {
55+ if let ast:: MacDelimiter :: Parenthesis = delim {
56+ return ;
57+ }
58+
59+ sess. span_diagnostic
60+ . struct_span_err ( span. entire ( ) , msg)
61+ . multipart_suggestion (
62+ "the delimiters should be `(` and `)`" ,
63+ vec ! [
64+ ( span. open, "(" . to_string( ) ) ,
65+ ( span. close, ")" . to_string( ) ) ,
66+ ] ,
67+ Applicability :: MachineApplicable ,
68+ )
69+ . emit ( ) ;
70+ }
71+
4072/// Checks that the given meta-item is compatible with this `AttributeTemplate`.
4173fn is_attr_template_compatible ( template : & AttributeTemplate , meta : & ast:: MetaItemKind ) -> bool {
4274 match meta {
0 commit comments