@@ -13,7 +13,7 @@ use tracing::debug;
1313#[ derive( Debug ) ]
1414pub enum InnerAttrPolicy < ' a > {
1515 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 > } ,
1717}
1818
1919const 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 \
2222pub ( super ) const DEFAULT_INNER_ATTR_FORBIDDEN : InnerAttrPolicy < ' _ > = InnerAttrPolicy :: Forbidden {
2323 reason : DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG ,
2424 saw_doc_comment : false ,
25- prev_attr_sp : None ,
25+ prev_outer_attr_sp : None ,
2626} ;
2727
2828enum OuterAttributeType {
@@ -34,22 +34,24 @@ enum OuterAttributeType {
3434impl < ' a > Parser < ' a > {
3535 /// Parses attributes that appear before an item.
3636 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 ( ) ;
3838 let mut just_parsed_doc_comment = false ;
3939 let start_pos = self . token_cursor . num_next_calls ;
4040 loop {
4141 let attr = if self . check ( & token:: Pound ) {
42+ let prev_outer_attr_sp = outer_attrs. last ( ) . map ( |attr| attr. span ) ;
43+
4244 let inner_error_reason = if just_parsed_doc_comment {
4345 "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 ( ) {
4547 "an inner attribute is not permitted following an outer attribute"
4648 } else {
4749 DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG
4850 } ;
4951 let inner_parse_policy = InnerAttrPolicy :: Forbidden {
5052 reason : inner_error_reason,
5153 saw_doc_comment : just_parsed_doc_comment,
52- prev_attr_sp : attrs . last ( ) . map ( |a| a . span ) ,
54+ prev_outer_attr_sp ,
5355 } ;
5456 just_parsed_doc_comment = false ;
5557 Some ( self . parse_attribute ( inner_parse_policy) ?)
@@ -97,12 +99,14 @@ impl<'a> Parser<'a> {
9799 } ;
98100
99101 if let Some ( attr) = attr {
100- attrs. push ( attr) ;
102+ if attr. style == ast:: AttrStyle :: Outer {
103+ outer_attrs. push ( attr) ;
104+ }
101105 } else {
102106 break ;
103107 }
104108 }
105- Ok ( AttrWrapper :: new ( attrs . into ( ) , start_pos) )
109+ Ok ( AttrWrapper :: new ( outer_attrs . into ( ) , start_pos) )
106110 }
107111
108112 /// Matches `attribute = # ! [ meta_item ]`.
@@ -215,15 +219,15 @@ impl<'a> Parser<'a> {
215219 }
216220
217221 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 =
220224 if saw_doc_comment { "previous doc comment" } else { "previous outer attribute" } ;
221225
222226 let mut diag = self . struct_span_err ( attr_sp, reason) ;
223227
224- if let Some ( prev_attr_sp ) = prev_attr_sp {
228+ if let Some ( prev_outer_attr_sp ) = prev_outer_attr_sp {
225229 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 ) ;
227231 }
228232
229233 diag. note (
0 commit comments