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 ;
4
16
17
+ /// ```rust
18
+ /// #[distributed_slice(crate)]
19
+ /// const MEOWS: [&str; _];
20
+ /// ```
5
21
pub ( crate ) fn distributed_slice (
6
22
_ecx : & mut ExtCtxt < ' _ > ,
7
23
span : Span ,
@@ -12,7 +28,7 @@ pub(crate) fn distributed_slice(
12
28
// FIXME(gr): check item
13
29
14
30
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" )
16
32
} ;
17
33
18
34
match & mut item. kind {
@@ -23,9 +39,58 @@ pub(crate) fn distributed_slice(
23
39
const_item. distributed_slice = DistributedSlice :: Declaration ( span) ;
24
40
}
25
41
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
+ ) ;
27
45
}
28
46
}
29
47
30
48
vec ! [ orig_item]
31
49
}
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