@@ -11,11 +11,13 @@ use crate::tokenstream::{DelimSpan, Spacing, TokenTree};
1111use crate :: tokenstream:: { LazyAttrTokenStream , TokenStream } ;
1212use crate :: util:: comments;
1313
14+ use rustc_data_structures:: sync:: WorkerLocal ;
1415use rustc_index:: bit_set:: GrowableBitSet ;
1516use rustc_span:: source_map:: BytePos ;
1617use rustc_span:: symbol:: { sym, Ident , Symbol } ;
1718use rustc_span:: Span ;
1819
20+ use std:: cell:: Cell ;
1921use std:: iter;
2022
2123pub struct MarkedAttrs ( GrowableBitSet < AttrId > ) ;
@@ -346,52 +348,67 @@ pub fn mk_nested_word_item(ident: Ident) -> NestedMetaItem {
346348 NestedMetaItem :: MetaItem ( mk_word_item ( ident) )
347349}
348350
349- pub ( crate ) fn mk_attr_id ( ) -> AttrId {
350- use std:: sync:: atomic:: AtomicU32 ;
351- use std:: sync:: atomic:: Ordering ;
351+ pub struct AttrIdGenerator ( WorkerLocal < Cell < u32 > > ) ;
352352
353- static NEXT_ATTR_ID : AtomicU32 = AtomicU32 :: new ( 0 ) ;
353+ impl AttrIdGenerator {
354+ pub fn new ( ) -> Self {
355+ // We use `(index as u32).reverse_bits()` to initialize the
356+ // starting value of AttrId in each worker thread.
357+ // The `index` is the index of the worker thread.
358+ // This ensures that the AttrId generated in each thread is unique.
359+ AttrIdGenerator ( WorkerLocal :: new ( |index| Cell :: new ( ( index as u32 ) . reverse_bits ( ) ) ) )
360+ }
354361
355- let id = NEXT_ATTR_ID . fetch_add ( 1 , Ordering :: SeqCst ) ;
356- assert ! ( id != u32 :: MAX ) ;
357- AttrId :: from_u32 ( id)
362+ pub fn mk_attr_id ( & self ) -> AttrId {
363+ let id = self . 0 . get ( ) ;
364+ self . 0 . set ( id + 1 ) ;
365+ AttrId :: from_u32 ( id)
366+ }
358367}
359368
360- pub fn mk_attr ( style : AttrStyle , path : Path , args : MacArgs , span : Span ) -> Attribute {
361- mk_attr_from_item ( AttrItem { path, args, tokens : None } , None , style, span)
369+ pub fn mk_attr (
370+ g : & AttrIdGenerator ,
371+ style : AttrStyle ,
372+ path : Path ,
373+ args : MacArgs ,
374+ span : Span ,
375+ ) -> Attribute {
376+ mk_attr_from_item ( g, AttrItem { path, args, tokens : None } , None , style, span)
362377}
363378
364379pub fn mk_attr_from_item (
380+ g : & AttrIdGenerator ,
365381 item : AttrItem ,
366382 tokens : Option < LazyAttrTokenStream > ,
367383 style : AttrStyle ,
368384 span : Span ,
369385) -> Attribute {
370386 Attribute {
371387 kind : AttrKind :: Normal ( P ( ast:: NormalAttr { item, tokens } ) ) ,
372- id : mk_attr_id ( ) ,
388+ id : g . mk_attr_id ( ) ,
373389 style,
374390 span,
375391 }
376392}
377393
378394/// Returns an inner attribute with the given value and span.
379- pub fn mk_attr_inner ( item : MetaItem ) -> Attribute {
380- mk_attr ( AttrStyle :: Inner , item. path , item. kind . mac_args ( item. span ) , item. span )
395+ pub fn mk_attr_inner ( g : & AttrIdGenerator , item : MetaItem ) -> Attribute {
396+ mk_attr ( g , AttrStyle :: Inner , item. path , item. kind . mac_args ( item. span ) , item. span )
381397}
382398
383399/// Returns an outer attribute with the given value and span.
384- pub fn mk_attr_outer ( item : MetaItem ) -> Attribute {
385- mk_attr ( AttrStyle :: Outer , item. path , item. kind . mac_args ( item. span ) , item. span )
400+ pub fn mk_attr_outer ( g : & AttrIdGenerator , item : MetaItem ) -> Attribute {
401+ mk_attr ( g , AttrStyle :: Outer , item. path , item. kind . mac_args ( item. span ) , item. span )
386402}
387403
388404pub fn mk_doc_comment (
405+ g : & AttrIdGenerator ,
389406 comment_kind : CommentKind ,
390407 style : AttrStyle ,
391408 data : Symbol ,
392409 span : Span ,
393410) -> Attribute {
394- Attribute { kind : AttrKind :: DocComment ( comment_kind, data) , id : mk_attr_id ( ) , style, span }
411+ Attribute { kind : AttrKind :: DocComment ( comment_kind, data) , id : g . mk_attr_id ( ) , style, span }
395412}
396413
397414pub fn list_contains_name ( items : & [ NestedMetaItem ] , name : Symbol ) -> bool {
0 commit comments