1
1
//! Meta-syntax validation logic of attributes for post-expansion.
2
2
3
+ use crate :: parse_in;
4
+
3
5
use rustc_errors:: { PResult , Applicability } ;
4
6
use 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 } ;
6
8
use syntax:: attr:: mk_name_value_item_str;
7
9
use syntax:: early_buffered_lints:: ILL_FORMED_ATTRIBUTE_INPUT ;
10
+ use syntax:: tokenstream:: DelimSpan ;
8
11
use syntax:: sess:: ParseSess ;
9
12
use syntax_pos:: { Symbol , sym} ;
10
13
@@ -27,16 +30,45 @@ pub fn check_meta(sess: &ParseSess, attr: &Attribute) {
27
30
pub fn parse_meta < ' a > ( sess : & ' a ParseSess , attr : & Attribute ) -> PResult < ' a , MetaItem > {
28
31
Ok ( match attr. kind {
29
32
AttrKind :: Normal ( ref item) => MetaItem {
30
- path : item. path . clone ( ) ,
31
- kind : super :: parse_in_attr ( sess, attr, |p| p. parse_meta_item_kind ( ) ) ?,
32
33
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
+ }
33
47
} ,
34
48
AttrKind :: DocComment ( comment) => {
35
49
mk_name_value_item_str ( Ident :: new ( sym:: doc, attr. span ) , comment, attr. span )
36
50
}
37
51
} )
38
52
}
39
53
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
+
40
72
/// Checks that the given meta-item is compatible with this `AttributeTemplate`.
41
73
fn is_attr_template_compatible ( template : & AttributeTemplate , meta : & ast:: MetaItemKind ) -> bool {
42
74
match meta {
0 commit comments