@@ -233,35 +233,52 @@ fn attrs_and_tokens_to_token_trees(
233
233
234
234
// Insert inner attribute tokens.
235
235
if !inner_attrs. is_empty ( ) {
236
- let mut found = false ;
237
- // Check the last two trees (to account for a trailing semi)
238
- for tree in res. iter_mut ( ) . rev ( ) . take ( 2 ) {
239
- if let TokenTree :: Delimited ( span, spacing, delim, delim_tokens) = tree {
240
- // Inner attributes are only supported on extern blocks, functions,
241
- // impls, and modules. All of these have their inner attributes
242
- // placed at the beginning of the rightmost outermost braced group:
243
- // e.g. fn foo() { #![my_attr] }
244
- //
245
- // Therefore, we can insert them back into the right location
246
- // without needing to do any extra position tracking.
247
- //
248
- // Note: Outline modules are an exception - they can
249
- // have attributes like `#![my_attr]` at the start of a file.
250
- // Support for custom attributes in this position is not
251
- // properly implemented - we always synthesize fake tokens,
252
- // so we never reach this code.
236
+ let found = insert_inner_attrs ( inner_attrs, res) ;
237
+ assert ! ( found, "Failed to find trailing delimited group in: {res:?}" ) ;
238
+ }
239
+
240
+ // Inner attributes are only supported on blocks, functions, impls, and
241
+ // modules. All of these have their inner attributes placed at the
242
+ // beginning of the rightmost outermost braced group:
243
+ // e.g. `fn foo() { #![my_attr] }`. (Note: the braces may be within
244
+ // invisible delimiters.)
245
+ //
246
+ // Therefore, we can insert them back into the right location without
247
+ // needing to do any extra position tracking.
248
+ //
249
+ // Note: Outline modules are an exception - they can have attributes like
250
+ // `#![my_attr]` at the start of a file. Support for custom attributes in
251
+ // this position is not properly implemented - we always synthesize fake
252
+ // tokens, so we never reach this code.
253
+ fn insert_inner_attrs ( inner_attrs : & [ Attribute ] , tts : & mut Vec < TokenTree > ) -> bool {
254
+ for tree in tts. iter_mut ( ) . rev ( ) {
255
+ if let TokenTree :: Delimited ( span, spacing, Delimiter :: Brace , stream) = tree {
256
+ // Found it: the rightmost, outermost braced group.
253
257
let mut tts = vec ! [ ] ;
254
258
for inner_attr in inner_attrs {
255
259
tts. extend ( inner_attr. token_trees ( ) ) ;
256
260
}
257
- tts. extend ( delim_tokens . 0 . iter ( ) . cloned ( ) ) ;
261
+ tts. extend ( stream . 0 . iter ( ) . cloned ( ) ) ;
258
262
let stream = TokenStream :: new ( tts) ;
259
- * tree = TokenTree :: Delimited ( * span, * spacing, * delim, stream) ;
260
- found = true ;
261
- break ;
263
+ * tree = TokenTree :: Delimited ( * span, * spacing, Delimiter :: Brace , stream) ;
264
+ return true ;
265
+ } else if let TokenTree :: Delimited ( span, spacing, Delimiter :: Invisible ( src) , stream) =
266
+ tree
267
+ {
268
+ // Recurse inside invisible delimiters.
269
+ let mut vec: Vec < _ > = stream. iter ( ) . cloned ( ) . collect ( ) ;
270
+ if insert_inner_attrs ( inner_attrs, & mut vec) {
271
+ * tree = TokenTree :: Delimited (
272
+ * span,
273
+ * spacing,
274
+ Delimiter :: Invisible ( * src) ,
275
+ TokenStream :: new ( vec) ,
276
+ ) ;
277
+ return true ;
278
+ }
262
279
}
263
280
}
264
- assert ! ( found , "Failed to find trailing delimited group in: {res:?}" ) ;
281
+ false
265
282
}
266
283
}
267
284
0 commit comments