@@ -2,10 +2,14 @@ use rustc_errors::DiagArgValue;
2
2
use rustc_feature:: { AttributeTemplate , template} ;
3
3
use rustc_hir:: Target ;
4
4
use rustc_hir:: attrs:: { AttributeKind , MacroUseArgs } ;
5
+ use rustc_hir:: lints:: AttributeLintKind ;
5
6
use rustc_span:: { Span , Symbol , sym} ;
6
7
use thin_vec:: ThinVec ;
7
8
8
- use crate :: attributes:: { AcceptMapping , AttributeParser , NoArgsAttributeParser , OnDuplicate } ;
9
+ use crate :: attributes:: {
10
+ AcceptMapping , AttributeOrder , AttributeParser , NoArgsAttributeParser , OnDuplicate ,
11
+ SingleAttributeParser ,
12
+ } ;
9
13
use crate :: context:: MaybeWarn :: { Allow , Error , Warn } ;
10
14
use crate :: context:: { AcceptContext , AllowedTargets , FinalizeContext , Stage } ;
11
15
use crate :: parser:: ArgParser ;
@@ -139,3 +143,63 @@ impl<S: Stage> NoArgsAttributeParser<S> for AllowInternalUnsafeParser {
139
143
] ) ;
140
144
const CREATE : fn ( Span ) -> AttributeKind = |span| AttributeKind :: AllowInternalUnsafe ( span) ;
141
145
}
146
+
147
+ pub ( crate ) struct MacroExportParser ;
148
+
149
+ impl < S : Stage > SingleAttributeParser < S > for crate :: attributes:: macro_attrs:: MacroExportParser {
150
+ const PATH : & [ Symbol ] = & [ sym:: macro_export] ;
151
+ const ATTRIBUTE_ORDER : AttributeOrder = AttributeOrder :: KeepOutermost ;
152
+ const ON_DUPLICATE : OnDuplicate < S > = OnDuplicate :: Warn ;
153
+ const TEMPLATE : AttributeTemplate = template ! ( Word , List : & [ "local_inner_macros" ] ) ;
154
+ const ALLOWED_TARGETS : AllowedTargets = AllowedTargets :: AllowListWarnRest ( & [
155
+ Allow ( Target :: MacroDef ) ,
156
+ Error ( Target :: WherePredicate ) ,
157
+ Error ( Target :: Crate ) ,
158
+ ] ) ;
159
+
160
+ fn convert ( cx : & mut AcceptContext < ' _ , ' _ , S > , args : & ArgParser < ' _ > ) -> Option < AttributeKind > {
161
+ let suggestions =
162
+ || <Self as SingleAttributeParser < S > >:: TEMPLATE . suggestions ( false , "macro_export" ) ;
163
+ let local_inner_macros = match args {
164
+ ArgParser :: NoArgs => false ,
165
+ ArgParser :: List ( list) => {
166
+ let Some ( l) = list. single ( ) else {
167
+ let span = cx. attr_span ;
168
+ cx. emit_lint (
169
+ AttributeLintKind :: InvalidMacroExportArguments {
170
+ suggestions : suggestions ( ) ,
171
+ } ,
172
+ span,
173
+ ) ;
174
+ return None ;
175
+ } ;
176
+ match l. meta_item ( ) . and_then ( |i| i. path ( ) . word_sym ( ) ) {
177
+ Some ( sym:: local_inner_macros) => true ,
178
+ _ => {
179
+ let span = cx. attr_span ;
180
+ cx. emit_lint (
181
+ AttributeLintKind :: InvalidMacroExportArguments {
182
+ suggestions : suggestions ( ) ,
183
+ } ,
184
+ span,
185
+ ) ;
186
+ return None ;
187
+ }
188
+ }
189
+ }
190
+ ArgParser :: NameValue ( _) => {
191
+ let span = cx. attr_span ;
192
+ let suggestions = suggestions ( ) ;
193
+ cx. emit_err ( session_diagnostics:: IllFormedAttributeInputLint {
194
+ num_suggestions : suggestions. len ( ) ,
195
+ suggestions : DiagArgValue :: StrListSepByAnd (
196
+ suggestions. into_iter ( ) . map ( |s| format ! ( "`{s}`" ) . into ( ) ) . collect ( ) ,
197
+ ) ,
198
+ span,
199
+ } ) ;
200
+ return None ;
201
+ }
202
+ } ;
203
+ Some ( AttributeKind :: MacroExport { span : cx. attr_span , local_inner_macros } )
204
+ }
205
+ }
0 commit comments