@@ -13,7 +13,7 @@ use tracing::debug;
13
13
#[ derive( Debug ) ]
14
14
pub enum InnerAttrPolicy < ' a > {
15
15
Permitted ,
16
- Forbidden { reason : & ' a str , saw_doc_comment : bool , prev_attr_sp : Option < Span > } ,
16
+ Forbidden { reason : & ' a str , saw_doc_comment : bool , prev_outer_attr_sp : Option < Span > } ,
17
17
}
18
18
19
19
const DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG : & str = "an inner attribute is not \
@@ -22,7 +22,7 @@ const DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG: &str = "an inner attribute is not \
22
22
pub ( super ) const DEFAULT_INNER_ATTR_FORBIDDEN : InnerAttrPolicy < ' _ > = InnerAttrPolicy :: Forbidden {
23
23
reason : DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG ,
24
24
saw_doc_comment : false ,
25
- prev_attr_sp : None ,
25
+ prev_outer_attr_sp : None ,
26
26
} ;
27
27
28
28
enum OuterAttributeType {
@@ -34,22 +34,24 @@ enum OuterAttributeType {
34
34
impl < ' a > Parser < ' a > {
35
35
/// Parses attributes that appear before an item.
36
36
pub ( super ) fn parse_outer_attributes ( & mut self ) -> PResult < ' a , AttrWrapper > {
37
- let mut attrs : Vec < ast:: Attribute > = Vec :: new ( ) ;
37
+ let mut outer_attrs : Vec < ast:: Attribute > = Vec :: new ( ) ;
38
38
let mut just_parsed_doc_comment = false ;
39
39
let start_pos = self . token_cursor . num_next_calls ;
40
40
loop {
41
41
let attr = if self . check ( & token:: Pound ) {
42
+ let prev_outer_attr_sp = outer_attrs. last ( ) . map ( |attr| attr. span ) ;
43
+
42
44
let inner_error_reason = if just_parsed_doc_comment {
43
45
"an inner attribute is not permitted following an outer doc comment"
44
- } else if !attrs . is_empty ( ) {
46
+ } else if prev_outer_attr_sp . is_some ( ) {
45
47
"an inner attribute is not permitted following an outer attribute"
46
48
} else {
47
49
DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG
48
50
} ;
49
51
let inner_parse_policy = InnerAttrPolicy :: Forbidden {
50
52
reason : inner_error_reason,
51
53
saw_doc_comment : just_parsed_doc_comment,
52
- prev_attr_sp : attrs . last ( ) . map ( |a| a . span ) ,
54
+ prev_outer_attr_sp ,
53
55
} ;
54
56
just_parsed_doc_comment = false ;
55
57
Some ( self . parse_attribute ( inner_parse_policy) ?)
@@ -97,12 +99,14 @@ impl<'a> Parser<'a> {
97
99
} ;
98
100
99
101
if let Some ( attr) = attr {
100
- attrs. push ( attr) ;
102
+ if attr. style == ast:: AttrStyle :: Outer {
103
+ outer_attrs. push ( attr) ;
104
+ }
101
105
} else {
102
106
break ;
103
107
}
104
108
}
105
- Ok ( AttrWrapper :: new ( attrs . into ( ) , start_pos) )
109
+ Ok ( AttrWrapper :: new ( outer_attrs . into ( ) , start_pos) )
106
110
}
107
111
108
112
/// Matches `attribute = # ! [ meta_item ]`.
@@ -215,15 +219,15 @@ impl<'a> Parser<'a> {
215
219
}
216
220
217
221
pub ( super ) fn error_on_forbidden_inner_attr ( & self , attr_sp : Span , policy : InnerAttrPolicy < ' _ > ) {
218
- if let InnerAttrPolicy :: Forbidden { reason, saw_doc_comment, prev_attr_sp } = policy {
219
- let prev_attr_note =
222
+ if let InnerAttrPolicy :: Forbidden { reason, saw_doc_comment, prev_outer_attr_sp } = policy {
223
+ let prev_outer_attr_note =
220
224
if saw_doc_comment { "previous doc comment" } else { "previous outer attribute" } ;
221
225
222
226
let mut diag = self . struct_span_err ( attr_sp, reason) ;
223
227
224
- if let Some ( prev_attr_sp ) = prev_attr_sp {
228
+ if let Some ( prev_outer_attr_sp ) = prev_outer_attr_sp {
225
229
diag. span_label ( attr_sp, "not permitted following an outer attribute" )
226
- . span_label ( prev_attr_sp , prev_attr_note ) ;
230
+ . span_label ( prev_outer_attr_sp , prev_outer_attr_note ) ;
227
231
}
228
232
229
233
diag. note (
0 commit comments