1- use rustc_ast:: { DistributedSlice , ItemKind , ast} ;
2- use rustc_expand:: base:: { Annotatable , ExtCtxt } ;
3- use rustc_span:: Span ;
1+ use rustc_ast:: ptr:: P ;
2+ use rustc_ast:: tokenstream:: TokenStream ;
3+ use rustc_ast:: {
4+ ConstItem , DUMMY_NODE_ID , Defaultness , DistributedSlice , Expr , Generics , Item , ItemKind , Path ,
5+ Ty , TyKind , ast,
6+ } ;
7+ use rustc_errors:: PResult ;
8+ use rustc_expand:: base:: {
9+ Annotatable , DummyResult , ExpandResult , ExtCtxt , MacEager , MacroExpanderResult ,
10+ } ;
11+ use rustc_parse:: exp;
12+ use rustc_parse:: parser:: { Parser , PathStyle } ;
13+ use rustc_span:: { Ident , Span , kw} ;
14+ use smallvec:: smallvec;
15+ use thin_vec:: ThinVec ;
416
17+ /// ```rust
18+ /// #[distributed_slice(crate)]
19+ /// const MEOWS: [&str; _];
20+ /// ```
521pub ( crate ) fn distributed_slice (
622 _ecx : & mut ExtCtxt < ' _ > ,
723 span : Span ,
@@ -12,7 +28,7 @@ pub(crate) fn distributed_slice(
1228 // FIXME(gr): check item
1329
1430 let Annotatable :: Item ( item) = & mut orig_item else {
15- panic ! ( "expected `#[distributed_slice]` on an item" )
31+ panic ! ( "expected `#[distributed_slice(crate) ]` on an item" )
1632 } ;
1733
1834 match & mut item. kind {
@@ -23,9 +39,58 @@ pub(crate) fn distributed_slice(
2339 const_item. distributed_slice = DistributedSlice :: Declaration ( span) ;
2440 }
2541 other => {
26- panic ! ( "expected `#[distributed_slice]` on a const or static item, not {other:?}" ) ;
42+ panic ! (
43+ "expected `#[distributed_slice(crate)]` on a const or static item, not {other:?}"
44+ ) ;
2745 }
2846 }
2947
3048 vec ! [ orig_item]
3149}
50+
51+ fn parse_element ( mut p : Parser < ' _ > ) -> PResult < ' _ , ( Path , P < Expr > ) > {
52+ let ident = p. parse_path ( PathStyle :: Expr ) ?;
53+ p. expect ( exp ! [ Comma ] ) ?;
54+ let expr = p. parse_expr ( ) ?;
55+
56+ // optional trailing comma
57+ let _ = p. eat ( exp ! [ Comma ] ) ;
58+
59+ Ok ( ( ident, expr) )
60+ }
61+
62+ /// ```rust
63+ /// distributed_slice_element!(MEOWS, "mrow");
64+ /// ```
65+ pub ( crate ) fn distributed_slice_element (
66+ cx : & mut ExtCtxt < ' _ > ,
67+ span : Span ,
68+ tts : TokenStream ,
69+ ) -> MacroExpanderResult < ' static > {
70+ let ( path, expr) = match parse_element ( cx. new_parser_from_tts ( tts) ) {
71+ Ok ( ( ident, expr) ) => ( ident, expr) ,
72+ Err ( err) => {
73+ let guar = err. emit ( ) ;
74+ return ExpandResult :: Ready ( DummyResult :: any ( span, guar) ) ;
75+ }
76+ } ;
77+
78+ ExpandResult :: Ready ( MacEager :: items ( smallvec ! [ P ( Item {
79+ attrs: ThinVec :: new( ) ,
80+ id: DUMMY_NODE_ID ,
81+ span,
82+ vis: ast:: Visibility { kind: ast:: VisibilityKind :: Inherited , span, tokens: None } ,
83+ kind: ItemKind :: Const ( Box :: new( ConstItem {
84+ defaultness: Defaultness :: Final ,
85+ ident: Ident { name: kw:: Underscore , span } ,
86+ generics: Generics :: default ( ) ,
87+ // leave out the ty, we discover it when
88+ // when name-resolving to the registry definition
89+ ty: P ( Ty { id: DUMMY_NODE_ID , kind: TyKind :: Infer , span, tokens: None } ) ,
90+ expr: Some ( expr) ,
91+ define_opaque: None ,
92+ distributed_slice: DistributedSlice :: Addition { declaration: path, id: DUMMY_NODE_ID }
93+ } ) ) ,
94+ tokens: None
95+ } ) ] ) )
96+ }
0 commit comments