@@ -14,6 +14,7 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
1414use rustc_errors:: { Applicability , Diag , ErrorGuaranteed , MultiSpan } ;
1515use rustc_feature:: Features ;
1616use rustc_hir as hir;
17+ use rustc_hir:: attrs:: diagnostic:: Directive ;
1718use rustc_hir:: def:: MacroKinds ;
1819use rustc_hir:: find_attr;
1920use rustc_lint_defs:: builtin:: {
@@ -164,6 +165,7 @@ pub struct MacroRulesMacroExpander {
164165 node_id : NodeId ,
165166 name : Ident ,
166167 span : Span ,
168+ on_missing_args : Option < Directive > ,
167169 transparency : Transparency ,
168170 kinds : MacroKinds ,
169171 rules : Vec < MacroRule > ,
@@ -194,7 +196,8 @@ impl MacroRulesMacroExpander {
194196 ) -> Result < TokenStream , ErrorGuaranteed > {
195197 // This is similar to `expand_macro`, but they have very different signatures, and will
196198 // diverge further once derives support arguments.
197- let Self { name, ref rules, node_id, .. } = * self ;
199+ let name = self . name ;
200+ let rules = & self . rules ;
198201 let psess = & cx. sess . psess ;
199202
200203 if cx. trace_macros ( ) {
@@ -220,8 +223,8 @@ impl MacroRulesMacroExpander {
220223 trace_macros_note ( & mut cx. expansions , sp, msg) ;
221224 }
222225
223- if is_defined_in_current_crate ( node_id) {
224- cx. resolver . record_macro_rule_usage ( node_id, rule_index) ;
226+ if is_defined_in_current_crate ( self . node_id ) {
227+ cx. resolver . record_macro_rule_usage ( self . node_id , rule_index) ;
225228 }
226229
227230 Ok ( tts)
@@ -236,6 +239,7 @@ impl MacroRulesMacroExpander {
236239 FailedMacro :: Derive ,
237240 body,
238241 rules,
242+ self . on_missing_args . as_ref ( ) ,
239243 ) ;
240244 cx. macro_error_and_trace_macros_diag ( ) ;
241245 Err ( guar)
@@ -260,6 +264,7 @@ impl TTMacroExpander for MacroRulesMacroExpander {
260264 self . transparency ,
261265 input,
262266 & self . rules ,
267+ self . on_missing_args . as_ref ( ) ,
263268 ) )
264269 }
265270}
@@ -294,6 +299,7 @@ impl AttrProcMacro for MacroRulesMacroExpander {
294299 args,
295300 body,
296301 & self . rules ,
302+ self . on_missing_args . as_ref ( ) ,
297303 )
298304 }
299305}
@@ -355,7 +361,7 @@ impl<'matcher> Tracker<'matcher> for NoopTracker {
355361}
356362
357363/// Expands the rules based macro defined by `rules` for a given input `arg`.
358- #[ instrument( skip( cx, transparency, arg, rules) ) ]
364+ #[ instrument( skip( cx, transparency, arg, rules, on_missing_args ) ) ]
359365fn expand_macro < ' cx , ' a : ' cx > (
360366 cx : & ' cx mut ExtCtxt < ' _ > ,
361367 sp : Span ,
@@ -365,6 +371,7 @@ fn expand_macro<'cx, 'a: 'cx>(
365371 transparency : Transparency ,
366372 arg : TokenStream ,
367373 rules : & ' a [ MacroRule ] ,
374+ on_missing_args : Option < & Directive > ,
368375) -> Box < dyn MacResult + ' cx > {
369376 let psess = & cx. sess . psess ;
370377
@@ -423,6 +430,7 @@ fn expand_macro<'cx, 'a: 'cx>(
423430 FailedMacro :: Func ,
424431 & arg,
425432 rules,
433+ on_missing_args,
426434 ) ;
427435 cx. macro_error_and_trace_macros_diag ( ) ;
428436 DummyResult :: any ( span, guar)
@@ -431,7 +439,7 @@ fn expand_macro<'cx, 'a: 'cx>(
431439}
432440
433441/// Expands the rules based macro defined by `rules` for a given attribute `args` and `body`.
434- #[ instrument( skip( cx, transparency, args, body, rules) ) ]
442+ #[ instrument( skip( cx, transparency, args, body, rules, on_missing_args ) ) ]
435443fn expand_macro_attr (
436444 cx : & mut ExtCtxt < ' _ > ,
437445 sp : Span ,
@@ -443,6 +451,7 @@ fn expand_macro_attr(
443451 args : TokenStream ,
444452 body : TokenStream ,
445453 rules : & [ MacroRule ] ,
454+ on_missing_args : Option < & Directive > ,
446455) -> Result < TokenStream , ErrorGuaranteed > {
447456 let psess = & cx. sess . psess ;
448457 // Macros defined in the current crate have a real node id,
@@ -507,6 +516,7 @@ fn expand_macro_attr(
507516 FailedMacro :: Attr ( & args) ,
508517 & body,
509518 rules,
519+ on_missing_args,
510520 ) ;
511521 cx. trace_macros_diag ( ) ;
512522 Err ( guar)
@@ -849,7 +859,22 @@ pub fn compile_declarative_macro(
849859 // Return the number of rules for unused rule linting, if this is a local macro.
850860 let nrules = if is_defined_in_current_crate ( node_id) { rules. len ( ) } else { 0 } ;
851861
852- let exp = MacroRulesMacroExpander { name : ident, kinds, span, node_id, transparency, rules } ;
862+ let on_missing_args = find_attr ! (
863+ attrs,
864+ OnMissingArgs { directive, .. } => directive. clone( )
865+ )
866+ . flatten ( )
867+ . map ( |directive| * directive) ;
868+
869+ let exp = MacroRulesMacroExpander {
870+ name : ident,
871+ kinds,
872+ span,
873+ node_id,
874+ on_missing_args,
875+ transparency,
876+ rules,
877+ } ;
853878 ( mk_syn_ext ( SyntaxExtensionKind :: MacroRules ( Arc :: new ( exp) ) ) , nrules)
854879}
855880
0 commit comments