@@ -12,7 +12,8 @@ use std::cmp;
12
12
13
13
use strings:: string_buffer:: StringBuffer ;
14
14
use syntax:: { ast, ptr, visit} ;
15
- use syntax:: codemap:: { self , BytePos , CodeMap , Span } ;
15
+ use syntax:: attr:: HasAttrs ;
16
+ use syntax:: codemap:: { self , BytePos , CodeMap , Pos , Span } ;
16
17
use syntax:: parse:: ParseSess ;
17
18
18
19
use { Indent , Shape , Spanned } ;
@@ -132,22 +133,45 @@ impl<'a> FmtVisitor<'a> {
132
133
self . buffer . push_str ( "{" ) ;
133
134
134
135
if self . config . remove_blank_lines_at_start_or_end_of_block ( ) {
135
- if let Some ( stmt) = b. stmts . first ( ) {
136
- let snippet = self . snippet ( mk_sp ( self . last_pos , stmt. span . lo ) ) ;
137
- let len = CommentCodeSlices :: new ( & snippet)
138
- . nth ( 0 )
139
- . and_then ( |( kind, _, s) | {
140
- if kind == CodeCharKind :: Normal {
141
- // There may be inner attributes
142
- let s = & s[ ..s. len ( ) -
143
- s. trim_left_matches ( & [ ' ' , '\t' , '\r' , '\n' ] [ ..] ) . len ( ) ] ;
144
- s. rfind ( '\n' )
136
+ if let Some ( first_stmt) = b. stmts . first ( ) {
137
+ let attr_lo = inner_attrs
138
+ . and_then ( |attrs| {
139
+ attrs
140
+ . iter ( )
141
+ . filter ( |a| a. style == ast:: AttrStyle :: Inner )
142
+ . nth ( 0 )
143
+ . map ( |attr| attr. span . lo )
144
+ } )
145
+ . or_else ( || {
146
+ // Attributes for an item in a statement position
147
+ // do not belong to the statement. (rust-lang/rust#34459)
148
+ if let ast:: StmtKind :: Item ( ref item) = first_stmt. node {
149
+ item. attrs . first ( )
145
150
} else {
146
- None
147
- }
151
+ first_stmt. attrs ( ) . first ( )
152
+ } . and_then ( |attr| {
153
+ // Some stmts can have embedded attributes.
154
+ // e.g. `match { #![attr] ... }`
155
+ let attr_lo = attr. span . lo ;
156
+ if attr_lo < first_stmt. span . lo {
157
+ Some ( attr_lo)
158
+ } else {
159
+ None
160
+ }
161
+ } )
148
162
} ) ;
163
+
164
+ let snippet =
165
+ self . snippet ( mk_sp ( self . last_pos , attr_lo. unwrap_or ( first_stmt. span . lo ) ) ) ;
166
+ let len = CommentCodeSlices :: new ( & snippet) . nth ( 0 ) . and_then (
167
+ |( kind, _, s) | if kind == CodeCharKind :: Normal {
168
+ s. rfind ( '\n' )
169
+ } else {
170
+ None
171
+ } ,
172
+ ) ;
149
173
if let Some ( len) = len {
150
- self . last_pos = self . last_pos + BytePos ( len as u32 ) ;
174
+ self . last_pos = self . last_pos + BytePos :: from_usize ( len) ;
151
175
}
152
176
}
153
177
}
@@ -186,7 +210,7 @@ impl<'a> FmtVisitor<'a> {
186
210
}
187
211
} ) ;
188
212
if let Some ( len) = len {
189
- remove_len = BytePos ( len as u32 ) ;
213
+ remove_len = BytePos :: from_usize ( len) ;
190
214
}
191
215
}
192
216
}
0 commit comments