@@ -201,7 +201,7 @@ impl<'a> Parser<'a> {
201
201
// tokens by definition).
202
202
let needs_collection = matches ! ( force_collect, ForceCollect :: Yes )
203
203
// - Any of our outer attributes require tokens.
204
- || !crate :: parser :: attr :: is_complete ( & attrs. attrs )
204
+ || !is_complete ( & attrs. attrs )
205
205
// - Our target supports custom inner attributes (custom
206
206
// inner attribute invocation might require token capturing).
207
207
|| R :: SUPPORTS_CUSTOM_INNER_ATTRS
@@ -261,7 +261,7 @@ impl<'a> Parser<'a> {
261
261
// outer and inner attributes. So this check is more precise than
262
262
// the earlier `is_complete()` check, and we don't need to
263
263
// check `R::SUPPORTS_CUSTOM_INNER_ATTRS`.)
264
- || !crate :: parser :: attr :: is_complete ( ret. attrs ( ) )
264
+ || !is_complete ( ret. attrs ( ) )
265
265
// - We are in `capture_cfg` mode and there are `#[cfg]` or
266
266
// `#[cfg_attr]` attributes. (During normal non-`capture_cfg`
267
267
// parsing, we don't need any special capturing for those
@@ -457,6 +457,17 @@ fn make_attr_token_stream(
457
457
AttrTokenStream :: new ( stack_top. inner )
458
458
}
459
459
460
+ /// The attributes are complete if all attributes are either a doc comment or a
461
+ /// builtin attribute other than `cfg_attr`.
462
+ fn is_complete ( attrs : & [ ast:: Attribute ] ) -> bool {
463
+ attrs. iter ( ) . all ( |attr| {
464
+ attr. is_doc_comment ( )
465
+ || attr. ident ( ) . is_some_and ( |ident| {
466
+ ident. name != sym:: cfg_attr && rustc_feature:: is_builtin_attr_name ( ident. name )
467
+ } )
468
+ } )
469
+ }
470
+
460
471
// Some types are used a lot. Make sure they don't unintentionally get bigger.
461
472
#[ cfg( target_pointer_width = "64" ) ]
462
473
mod size_asserts {
0 commit comments