]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_expand/src/mbe/macro_rules.rs
Auto merge of #2665 - RalfJung:rustup, r=RalfJung
[rust.git] / compiler / rustc_expand / src / mbe / macro_rules.rs
1 use crate::base::{DummyResult, ExtCtxt, MacResult, TTMacroExpander};
2 use crate::base::{SyntaxExtension, SyntaxExtensionKind};
3 use crate::expand::{ensure_complete_parse, parse_ast_fragment, AstFragment, AstFragmentKind};
4 use crate::mbe;
5 use crate::mbe::macro_check;
6 use crate::mbe::macro_parser::{Error, ErrorReported, Failure, Success, TtParser};
7 use crate::mbe::macro_parser::{MatchedSeq, MatchedTokenTree, MatcherLoc};
8 use crate::mbe::transcribe::transcribe;
9
10 use rustc_ast as ast;
11 use rustc_ast::token::{self, Delimiter, NonterminalKind, Token, TokenKind, TokenKind::*};
12 use rustc_ast::tokenstream::{DelimSpan, TokenStream};
13 use rustc_ast::{NodeId, DUMMY_NODE_ID};
14 use rustc_ast_pretty::pprust;
15 use rustc_attr::{self as attr, TransparencyError};
16 use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
17 use rustc_errors::{
18     Applicability, Diagnostic, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed,
19 };
20 use rustc_feature::Features;
21 use rustc_lint_defs::builtin::{
22     RUST_2021_INCOMPATIBLE_OR_PATTERNS, SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
23 };
24 use rustc_lint_defs::BuiltinLintDiagnostics;
25 use rustc_parse::parser::Parser;
26 use rustc_session::parse::ParseSess;
27 use rustc_session::Session;
28 use rustc_span::edition::Edition;
29 use rustc_span::hygiene::Transparency;
30 use rustc_span::source_map::SourceMap;
31 use rustc_span::symbol::{kw, sym, Ident, MacroRulesNormalizedIdent};
32 use rustc_span::Span;
33
34 use std::borrow::Cow;
35 use std::collections::hash_map::Entry;
36 use std::{mem, slice};
37
38 use super::macro_parser::{NamedMatches, NamedParseResult};
39
40 pub(crate) struct ParserAnyMacro<'a> {
41     parser: Parser<'a>,
42
43     /// Span of the expansion site of the macro this parser is for
44     site_span: Span,
45     /// The ident of the macro we're parsing
46     macro_ident: Ident,
47     lint_node_id: NodeId,
48     is_trailing_mac: bool,
49     arm_span: Span,
50     /// Whether or not this macro is defined in the current crate
51     is_local: bool,
52 }
53
54 pub(crate) fn annotate_err_with_kind(err: &mut Diagnostic, kind: AstFragmentKind, span: Span) {
55     match kind {
56         AstFragmentKind::Ty => {
57             err.span_label(span, "this macro call doesn't expand to a type");
58         }
59         AstFragmentKind::Pat => {
60             err.span_label(span, "this macro call doesn't expand to a pattern");
61         }
62         _ => {}
63     };
64 }
65
66 fn emit_frag_parse_err(
67     mut e: DiagnosticBuilder<'_, rustc_errors::ErrorGuaranteed>,
68     parser: &Parser<'_>,
69     orig_parser: &mut Parser<'_>,
70     site_span: Span,
71     arm_span: Span,
72     kind: AstFragmentKind,
73 ) {
74     // FIXME(davidtwco): avoid depending on the error message text
75     if parser.token == token::Eof
76         && let DiagnosticMessage::Str(message) = &e.message[0].0
77         && message.ends_with(", found `<eof>`")
78     {
79         let msg = &e.message[0];
80         e.message[0] = (
81             DiagnosticMessage::Str(format!(
82                 "macro expansion ends with an incomplete expression: {}",
83                 message.replace(", found `<eof>`", ""),
84             )),
85             msg.1,
86         );
87         if !e.span.is_dummy() {
88             // early end of macro arm (#52866)
89             e.replace_span_with(parser.token.span.shrink_to_hi());
90         }
91     }
92     if e.span.is_dummy() {
93         // Get around lack of span in error (#30128)
94         e.replace_span_with(site_span);
95         if !parser.sess.source_map().is_imported(arm_span) {
96             e.span_label(arm_span, "in this macro arm");
97         }
98     } else if parser.sess.source_map().is_imported(parser.token.span) {
99         e.span_label(site_span, "in this macro invocation");
100     }
101     match kind {
102         // Try a statement if an expression is wanted but failed and suggest adding `;` to call.
103         AstFragmentKind::Expr => match parse_ast_fragment(orig_parser, AstFragmentKind::Stmts) {
104             Err(err) => err.cancel(),
105             Ok(_) => {
106                 e.note(
107                     "the macro call doesn't expand to an expression, but it can expand to a statement",
108                 );
109                 e.span_suggestion_verbose(
110                     site_span.shrink_to_hi(),
111                     "add `;` to interpret the expansion as a statement",
112                     ";",
113                     Applicability::MaybeIncorrect,
114                 );
115             }
116         },
117         _ => annotate_err_with_kind(&mut e, kind, site_span),
118     };
119     e.emit();
120 }
121
122 impl<'a> ParserAnyMacro<'a> {
123     pub(crate) fn make(mut self: Box<ParserAnyMacro<'a>>, kind: AstFragmentKind) -> AstFragment {
124         let ParserAnyMacro {
125             site_span,
126             macro_ident,
127             ref mut parser,
128             lint_node_id,
129             arm_span,
130             is_trailing_mac,
131             is_local,
132         } = *self;
133         let snapshot = &mut parser.create_snapshot_for_diagnostic();
134         let fragment = match parse_ast_fragment(parser, kind) {
135             Ok(f) => f,
136             Err(err) => {
137                 emit_frag_parse_err(err, parser, snapshot, site_span, arm_span, kind);
138                 return kind.dummy(site_span);
139             }
140         };
141
142         // We allow semicolons at the end of expressions -- e.g., the semicolon in
143         // `macro_rules! m { () => { panic!(); } }` isn't parsed by `.parse_expr()`,
144         // but `m!()` is allowed in expression positions (cf. issue #34706).
145         if kind == AstFragmentKind::Expr && parser.token == token::Semi {
146             if is_local {
147                 parser.sess.buffer_lint_with_diagnostic(
148                     SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
149                     parser.token.span,
150                     lint_node_id,
151                     "trailing semicolon in macro used in expression position",
152                     BuiltinLintDiagnostics::TrailingMacro(is_trailing_mac, macro_ident),
153                 );
154             }
155             parser.bump();
156         }
157
158         // Make sure we don't have any tokens left to parse so we don't silently drop anything.
159         let path = ast::Path::from_ident(macro_ident.with_span_pos(site_span));
160         ensure_complete_parse(parser, &path, kind.name(), site_span);
161         fragment
162     }
163 }
164
165 struct MacroRulesMacroExpander {
166     node_id: NodeId,
167     name: Ident,
168     span: Span,
169     transparency: Transparency,
170     lhses: Vec<Vec<MatcherLoc>>,
171     rhses: Vec<mbe::TokenTree>,
172     valid: bool,
173 }
174
175 impl TTMacroExpander for MacroRulesMacroExpander {
176     fn expand<'cx>(
177         &self,
178         cx: &'cx mut ExtCtxt<'_>,
179         sp: Span,
180         input: TokenStream,
181     ) -> Box<dyn MacResult + 'cx> {
182         if !self.valid {
183             return DummyResult::any(sp);
184         }
185         expand_macro(
186             cx,
187             sp,
188             self.span,
189             self.node_id,
190             self.name,
191             self.transparency,
192             input,
193             &self.lhses,
194             &self.rhses,
195         )
196     }
197 }
198
199 fn macro_rules_dummy_expander<'cx>(
200     _: &'cx mut ExtCtxt<'_>,
201     span: Span,
202     _: TokenStream,
203 ) -> Box<dyn MacResult + 'cx> {
204     DummyResult::any(span)
205 }
206
207 fn trace_macros_note(cx_expansions: &mut FxIndexMap<Span, Vec<String>>, sp: Span, message: String) {
208     let sp = sp.macro_backtrace().last().map_or(sp, |trace| trace.call_site);
209     cx_expansions.entry(sp).or_default().push(message);
210 }
211
212 pub(super) trait Tracker<'matcher> {
213     /// This is called before trying to match next MatcherLoc on the current token.
214     fn before_match_loc(&mut self, parser: &TtParser, matcher: &'matcher MatcherLoc);
215
216     /// This is called after an arm has been parsed, either successfully or unsuccessfully. When this is called,
217     /// `before_match_loc` was called at least once (with a `MatcherLoc::Eof`).
218     fn after_arm(&mut self, result: &NamedParseResult);
219
220     /// For tracing.
221     fn description() -> &'static str;
222 }
223
224 /// A noop tracker that is used in the hot path of the expansion, has zero overhead thanks to monomorphization.
225 struct NoopTracker;
226
227 impl<'matcher> Tracker<'matcher> for NoopTracker {
228     fn before_match_loc(&mut self, _: &TtParser, _: &'matcher MatcherLoc) {}
229     fn after_arm(&mut self, _: &NamedParseResult) {}
230     fn description() -> &'static str {
231         "none"
232     }
233 }
234
235 /// Expands the rules based macro defined by `lhses` and `rhses` for a given
236 /// input `arg`.
237 #[instrument(skip(cx, transparency, arg, lhses, rhses))]
238 fn expand_macro<'cx>(
239     cx: &'cx mut ExtCtxt<'_>,
240     sp: Span,
241     def_span: Span,
242     node_id: NodeId,
243     name: Ident,
244     transparency: Transparency,
245     arg: TokenStream,
246     lhses: &[Vec<MatcherLoc>],
247     rhses: &[mbe::TokenTree],
248 ) -> Box<dyn MacResult + 'cx> {
249     let sess = &cx.sess.parse_sess;
250     // Macros defined in the current crate have a real node id,
251     // whereas macros from an external crate have a dummy id.
252     let is_local = node_id != DUMMY_NODE_ID;
253
254     if cx.trace_macros() {
255         let msg = format!("expanding `{}! {{ {} }}`", name, pprust::tts_to_string(&arg));
256         trace_macros_note(&mut cx.expansions, sp, msg);
257     }
258
259     // Track nothing for the best performance.
260     let try_success_result = try_match_macro(sess, name, &arg, lhses, &mut NoopTracker);
261
262     match try_success_result {
263         Ok((i, named_matches)) => {
264             let (rhs, rhs_span): (&mbe::Delimited, DelimSpan) = match &rhses[i] {
265                 mbe::TokenTree::Delimited(span, delimited) => (&delimited, *span),
266                 _ => cx.span_bug(sp, "malformed macro rhs"),
267             };
268             let arm_span = rhses[i].span();
269
270             let rhs_spans = rhs.tts.iter().map(|t| t.span()).collect::<Vec<_>>();
271             // rhs has holes ( `$id` and `$(...)` that need filled)
272             let mut tts = match transcribe(cx, &named_matches, &rhs, rhs_span, transparency) {
273                 Ok(tts) => tts,
274                 Err(mut err) => {
275                     err.emit();
276                     return DummyResult::any(arm_span);
277                 }
278             };
279
280             // Replace all the tokens for the corresponding positions in the macro, to maintain
281             // proper positions in error reporting, while maintaining the macro_backtrace.
282             if rhs_spans.len() == tts.len() {
283                 tts = tts.map_enumerated(|i, tt| {
284                     let mut tt = tt.clone();
285                     let mut sp = rhs_spans[i];
286                     sp = sp.with_ctxt(tt.span().ctxt());
287                     tt.set_span(sp);
288                     tt
289                 });
290             }
291
292             if cx.trace_macros() {
293                 let msg = format!("to `{}`", pprust::tts_to_string(&tts));
294                 trace_macros_note(&mut cx.expansions, sp, msg);
295             }
296
297             let mut p = Parser::new(sess, tts, false, None);
298             p.last_type_ascription = cx.current_expansion.prior_type_ascription;
299
300             if is_local {
301                 cx.resolver.record_macro_rule_usage(node_id, i);
302             }
303
304             // Let the context choose how to interpret the result.
305             // Weird, but useful for X-macros.
306             return Box::new(ParserAnyMacro {
307                 parser: p,
308
309                 // Pass along the original expansion site and the name of the macro
310                 // so we can print a useful error message if the parse of the expanded
311                 // macro leaves unparsed tokens.
312                 site_span: sp,
313                 macro_ident: name,
314                 lint_node_id: cx.current_expansion.lint_node_id,
315                 is_trailing_mac: cx.current_expansion.is_trailing_mac,
316                 arm_span,
317                 is_local,
318             });
319         }
320         Err(CanRetry::No(_)) => {
321             debug!("Will not retry matching as an error was emitted already");
322             return DummyResult::any(sp);
323         }
324         Err(CanRetry::Yes) => {
325             // Retry and emit a better error below.
326         }
327     }
328
329     // An error occurred, try the expansion again, tracking the expansion closely for better diagnostics.
330     let mut tracker = CollectTrackerAndEmitter::new(cx, sp);
331
332     let try_success_result = try_match_macro(sess, name, &arg, lhses, &mut tracker);
333     assert!(try_success_result.is_err(), "Macro matching returned a success on the second try");
334
335     if let Some(result) = tracker.result {
336         // An irrecoverable error occurred and has been emitted.
337         return result;
338     }
339
340     let Some((token, label)) = tracker.best_failure else {
341         return tracker.result.expect("must have encountered Error or ErrorReported");
342     };
343
344     let span = token.span.substitute_dummy(sp);
345
346     let mut err = cx.struct_span_err(span, &parse_failure_msg(&token));
347     err.span_label(span, label);
348     if !def_span.is_dummy() && !cx.source_map().is_imported(def_span) {
349         err.span_label(cx.source_map().guess_head_span(def_span), "when calling this macro");
350     }
351
352     annotate_doc_comment(&mut err, sess.source_map(), span);
353
354     // Check whether there's a missing comma in this macro call, like `println!("{}" a);`
355     if let Some((arg, comma_span)) = arg.add_comma() {
356         for lhs in lhses {
357             let parser = parser_from_cx(sess, arg.clone());
358             let mut tt_parser = TtParser::new(name);
359
360             if let Success(_) =
361                 tt_parser.parse_tt(&mut Cow::Borrowed(&parser), lhs, &mut NoopTracker)
362             {
363                 if comma_span.is_dummy() {
364                     err.note("you might be missing a comma");
365                 } else {
366                     err.span_suggestion_short(
367                         comma_span,
368                         "missing comma here",
369                         ", ",
370                         Applicability::MachineApplicable,
371                     );
372                 }
373             }
374         }
375     }
376     err.emit();
377     cx.trace_macros_diag();
378     DummyResult::any(sp)
379 }
380
381 /// The tracker used for the slow error path that collects useful info for diagnostics.
382 struct CollectTrackerAndEmitter<'a, 'cx> {
383     cx: &'a mut ExtCtxt<'cx>,
384     /// Which arm's failure should we report? (the one furthest along)
385     best_failure: Option<(Token, &'static str)>,
386     root_span: Span,
387     result: Option<Box<dyn MacResult + 'cx>>,
388 }
389
390 impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx> {
391     fn before_match_loc(&mut self, _parser: &TtParser, _matcher: &'matcher MatcherLoc) {
392         // Empty for now.
393     }
394
395     fn after_arm(&mut self, result: &NamedParseResult) {
396         match result {
397             Success(_) => {
398                 unreachable!("should not collect detailed info for successful macro match");
399             }
400             Failure(token, msg) => match self.best_failure {
401                 Some((ref best_token, _)) if best_token.span.lo() >= token.span.lo() => {}
402                 _ => self.best_failure = Some((token.clone(), msg)),
403             },
404             Error(err_sp, msg) => {
405                 let span = err_sp.substitute_dummy(self.root_span);
406                 self.cx.struct_span_err(span, msg).emit();
407                 self.result = Some(DummyResult::any(span));
408             }
409             ErrorReported(_) => self.result = Some(DummyResult::any(self.root_span)),
410         }
411     }
412
413     fn description() -> &'static str {
414         "detailed"
415     }
416 }
417
418 impl<'a, 'cx> CollectTrackerAndEmitter<'a, 'cx> {
419     fn new(cx: &'a mut ExtCtxt<'cx>, root_span: Span) -> Self {
420         Self { cx, best_failure: None, root_span, result: None }
421     }
422 }
423
424 enum CanRetry {
425     Yes,
426     /// We are not allowed to retry macro expansion as a fatal error has been emitted already.
427     No(ErrorGuaranteed),
428 }
429
430 /// Try expanding the macro. Returns the index of the successful arm and its named_matches if it was successful,
431 /// and nothing if it failed. On failure, it's the callers job to use `track` accordingly to record all errors
432 /// correctly.
433 #[instrument(level = "debug", skip(sess, arg, lhses, track), fields(tracking = %T::description()))]
434 fn try_match_macro<'matcher, T: Tracker<'matcher>>(
435     sess: &ParseSess,
436     name: Ident,
437     arg: &TokenStream,
438     lhses: &'matcher [Vec<MatcherLoc>],
439     track: &mut T,
440 ) -> Result<(usize, NamedMatches), CanRetry> {
441     // We create a base parser that can be used for the "black box" parts.
442     // Every iteration needs a fresh copy of that parser. However, the parser
443     // is not mutated on many of the iterations, particularly when dealing with
444     // macros like this:
445     //
446     // macro_rules! foo {
447     //     ("a") => (A);
448     //     ("b") => (B);
449     //     ("c") => (C);
450     //     // ... etc. (maybe hundreds more)
451     // }
452     //
453     // as seen in the `html5ever` benchmark. We use a `Cow` so that the base
454     // parser is only cloned when necessary (upon mutation). Furthermore, we
455     // reinitialize the `Cow` with the base parser at the start of every
456     // iteration, so that any mutated parsers are not reused. This is all quite
457     // hacky, but speeds up the `html5ever` benchmark significantly. (Issue
458     // 68836 suggests a more comprehensive but more complex change to deal with
459     // this situation.)
460     // FIXME(Nilstrieb): Stop recovery from happening on this parser and retry later with recovery if the macro failed to match.
461     let parser = parser_from_cx(sess, arg.clone());
462     // Try each arm's matchers.
463     let mut tt_parser = TtParser::new(name);
464     for (i, lhs) in lhses.iter().enumerate() {
465         let _tracing_span = trace_span!("Matching arm", %i);
466
467         // Take a snapshot of the state of pre-expansion gating at this point.
468         // This is used so that if a matcher is not `Success(..)`ful,
469         // then the spans which became gated when parsing the unsuccessful matcher
470         // are not recorded. On the first `Success(..)`ful matcher, the spans are merged.
471         let mut gated_spans_snapshot = mem::take(&mut *sess.gated_spans.spans.borrow_mut());
472
473         let result = tt_parser.parse_tt(&mut Cow::Borrowed(&parser), lhs, track);
474
475         track.after_arm(&result);
476
477         match result {
478             Success(named_matches) => {
479                 debug!("Parsed arm successfully");
480                 // The matcher was `Success(..)`ful.
481                 // Merge the gated spans from parsing the matcher with the pre-existing ones.
482                 sess.gated_spans.merge(gated_spans_snapshot);
483
484                 return Ok((i, named_matches));
485             }
486             Failure(_, _) => {
487                 trace!("Failed to match arm, trying the next one");
488                 // Try the next arm.
489             }
490             Error(_, _) => {
491                 debug!("Fatal error occurred during matching");
492                 // We haven't emitted an error yet, so we can retry.
493                 return Err(CanRetry::Yes);
494             }
495             ErrorReported(guarantee) => {
496                 debug!("Fatal error occurred and was reported during matching");
497                 // An error has been reported already, we cannot retry as that would cause duplicate errors.
498                 return Err(CanRetry::No(guarantee));
499             }
500         }
501
502         // The matcher was not `Success(..)`ful.
503         // Restore to the state before snapshotting and maybe try again.
504         mem::swap(&mut gated_spans_snapshot, &mut sess.gated_spans.spans.borrow_mut());
505     }
506
507     Err(CanRetry::Yes)
508 }
509
510 // Note that macro-by-example's input is also matched against a token tree:
511 //                   $( $lhs:tt => $rhs:tt );+
512 //
513 // Holy self-referential!
514
515 /// Converts a macro item into a syntax extension.
516 pub fn compile_declarative_macro(
517     sess: &Session,
518     features: &Features,
519     def: &ast::Item,
520     edition: Edition,
521 ) -> (SyntaxExtension, Vec<(usize, Span)>) {
522     debug!("compile_declarative_macro: {:?}", def);
523     let mk_syn_ext = |expander| {
524         SyntaxExtension::new(
525             sess,
526             SyntaxExtensionKind::LegacyBang(expander),
527             def.span,
528             Vec::new(),
529             edition,
530             def.ident.name,
531             &def.attrs,
532         )
533     };
534     let dummy_syn_ext = || (mk_syn_ext(Box::new(macro_rules_dummy_expander)), Vec::new());
535
536     let diag = &sess.parse_sess.span_diagnostic;
537     let lhs_nm = Ident::new(sym::lhs, def.span);
538     let rhs_nm = Ident::new(sym::rhs, def.span);
539     let tt_spec = Some(NonterminalKind::TT);
540
541     // Parse the macro_rules! invocation
542     let (macro_rules, body) = match &def.kind {
543         ast::ItemKind::MacroDef(def) => (def.macro_rules, def.body.inner_tokens()),
544         _ => unreachable!(),
545     };
546
547     // The pattern that macro_rules matches.
548     // The grammar for macro_rules! is:
549     // $( $lhs:tt => $rhs:tt );+
550     // ...quasiquoting this would be nice.
551     // These spans won't matter, anyways
552     let argument_gram = vec![
553         mbe::TokenTree::Sequence(
554             DelimSpan::dummy(),
555             mbe::SequenceRepetition {
556                 tts: vec![
557                     mbe::TokenTree::MetaVarDecl(def.span, lhs_nm, tt_spec),
558                     mbe::TokenTree::token(token::FatArrow, def.span),
559                     mbe::TokenTree::MetaVarDecl(def.span, rhs_nm, tt_spec),
560                 ],
561                 separator: Some(Token::new(
562                     if macro_rules { token::Semi } else { token::Comma },
563                     def.span,
564                 )),
565                 kleene: mbe::KleeneToken::new(mbe::KleeneOp::OneOrMore, def.span),
566                 num_captures: 2,
567             },
568         ),
569         // to phase into semicolon-termination instead of semicolon-separation
570         mbe::TokenTree::Sequence(
571             DelimSpan::dummy(),
572             mbe::SequenceRepetition {
573                 tts: vec![mbe::TokenTree::token(
574                     if macro_rules { token::Semi } else { token::Comma },
575                     def.span,
576                 )],
577                 separator: None,
578                 kleene: mbe::KleeneToken::new(mbe::KleeneOp::ZeroOrMore, def.span),
579                 num_captures: 0,
580             },
581         ),
582     ];
583     // Convert it into `MatcherLoc` form.
584     let argument_gram = mbe::macro_parser::compute_locs(&argument_gram);
585
586     let parser = Parser::new(&sess.parse_sess, body, true, rustc_parse::MACRO_ARGUMENTS);
587     let mut tt_parser =
588         TtParser::new(Ident::with_dummy_span(if macro_rules { kw::MacroRules } else { kw::Macro }));
589     let argument_map =
590         match tt_parser.parse_tt(&mut Cow::Owned(parser), &argument_gram, &mut NoopTracker) {
591             Success(m) => m,
592             Failure(token, msg) => {
593                 let s = parse_failure_msg(&token);
594                 let sp = token.span.substitute_dummy(def.span);
595                 let mut err = sess.parse_sess.span_diagnostic.struct_span_err(sp, &s);
596                 err.span_label(sp, msg);
597                 annotate_doc_comment(&mut err, sess.source_map(), sp);
598                 err.emit();
599                 return dummy_syn_ext();
600             }
601             Error(sp, msg) => {
602                 sess.parse_sess
603                     .span_diagnostic
604                     .struct_span_err(sp.substitute_dummy(def.span), &msg)
605                     .emit();
606                 return dummy_syn_ext();
607             }
608             ErrorReported(_) => {
609                 return dummy_syn_ext();
610             }
611         };
612
613     let mut valid = true;
614
615     // Extract the arguments:
616     let lhses = match argument_map[&MacroRulesNormalizedIdent::new(lhs_nm)] {
617         MatchedSeq(ref s) => s
618             .iter()
619             .map(|m| {
620                 if let MatchedTokenTree(ref tt) = *m {
621                     let tt = mbe::quoted::parse(
622                         TokenStream::new(vec![tt.clone()]),
623                         true,
624                         &sess.parse_sess,
625                         def.id,
626                         features,
627                         edition,
628                     )
629                     .pop()
630                     .unwrap();
631                     valid &= check_lhs_nt_follows(&sess.parse_sess, &def, &tt);
632                     return tt;
633                 }
634                 sess.parse_sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs")
635             })
636             .collect::<Vec<mbe::TokenTree>>(),
637         _ => sess.parse_sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs"),
638     };
639
640     let rhses = match argument_map[&MacroRulesNormalizedIdent::new(rhs_nm)] {
641         MatchedSeq(ref s) => s
642             .iter()
643             .map(|m| {
644                 if let MatchedTokenTree(ref tt) = *m {
645                     return mbe::quoted::parse(
646                         TokenStream::new(vec![tt.clone()]),
647                         false,
648                         &sess.parse_sess,
649                         def.id,
650                         features,
651                         edition,
652                     )
653                     .pop()
654                     .unwrap();
655                 }
656                 sess.parse_sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs")
657             })
658             .collect::<Vec<mbe::TokenTree>>(),
659         _ => sess.parse_sess.span_diagnostic.span_bug(def.span, "wrong-structured rhs"),
660     };
661
662     for rhs in &rhses {
663         valid &= check_rhs(&sess.parse_sess, rhs);
664     }
665
666     // don't abort iteration early, so that errors for multiple lhses can be reported
667     for lhs in &lhses {
668         valid &= check_lhs_no_empty_seq(&sess.parse_sess, slice::from_ref(lhs));
669     }
670
671     valid &= macro_check::check_meta_variables(&sess.parse_sess, def.id, def.span, &lhses, &rhses);
672
673     let (transparency, transparency_error) = attr::find_transparency(&def.attrs, macro_rules);
674     match transparency_error {
675         Some(TransparencyError::UnknownTransparency(value, span)) => {
676             diag.span_err(span, &format!("unknown macro transparency: `{}`", value));
677         }
678         Some(TransparencyError::MultipleTransparencyAttrs(old_span, new_span)) => {
679             diag.span_err(vec![old_span, new_span], "multiple macro transparency attributes");
680         }
681         None => {}
682     }
683
684     // Compute the spans of the macro rules for unused rule linting.
685     // To avoid warning noise, only consider the rules of this
686     // macro for the lint, if all rules are valid.
687     // Also, we are only interested in non-foreign macros.
688     let rule_spans = if valid && def.id != DUMMY_NODE_ID {
689         lhses
690             .iter()
691             .zip(rhses.iter())
692             .enumerate()
693             // If the rhs contains an invocation like compile_error!,
694             // don't consider the rule for the unused rule lint.
695             .filter(|(_idx, (_lhs, rhs))| !has_compile_error_macro(rhs))
696             // We only take the span of the lhs here,
697             // so that the spans of created warnings are smaller.
698             .map(|(idx, (lhs, _rhs))| (idx, lhs.span()))
699             .collect::<Vec<_>>()
700     } else {
701         Vec::new()
702     };
703
704     // Convert the lhses into `MatcherLoc` form, which is better for doing the
705     // actual matching. Unless the matcher is invalid.
706     let lhses = if valid {
707         lhses
708             .iter()
709             .map(|lhs| {
710                 // Ignore the delimiters around the matcher.
711                 match lhs {
712                     mbe::TokenTree::Delimited(_, delimited) => {
713                         mbe::macro_parser::compute_locs(&delimited.tts)
714                     }
715                     _ => sess.parse_sess.span_diagnostic.span_bug(def.span, "malformed macro lhs"),
716                 }
717             })
718             .collect()
719     } else {
720         vec![]
721     };
722
723     let expander = Box::new(MacroRulesMacroExpander {
724         name: def.ident,
725         span: def.span,
726         node_id: def.id,
727         transparency,
728         lhses,
729         rhses,
730         valid,
731     });
732     (mk_syn_ext(expander), rule_spans)
733 }
734
735 #[derive(Subdiagnostic)]
736 enum ExplainDocComment {
737     #[label(expand_explain_doc_comment_inner)]
738     Inner {
739         #[primary_span]
740         span: Span,
741     },
742     #[label(expand_explain_doc_comment_outer)]
743     Outer {
744         #[primary_span]
745         span: Span,
746     },
747 }
748
749 fn annotate_doc_comment(err: &mut Diagnostic, sm: &SourceMap, span: Span) {
750     if let Ok(src) = sm.span_to_snippet(span) {
751         if src.starts_with("///") || src.starts_with("/**") {
752             err.subdiagnostic(ExplainDocComment::Outer { span });
753         } else if src.starts_with("//!") || src.starts_with("/*!") {
754             err.subdiagnostic(ExplainDocComment::Inner { span });
755         }
756     }
757 }
758
759 fn check_lhs_nt_follows(sess: &ParseSess, def: &ast::Item, lhs: &mbe::TokenTree) -> bool {
760     // lhs is going to be like TokenTree::Delimited(...), where the
761     // entire lhs is those tts. Or, it can be a "bare sequence", not wrapped in parens.
762     if let mbe::TokenTree::Delimited(_, delimited) = lhs {
763         check_matcher(sess, def, &delimited.tts)
764     } else {
765         let msg = "invalid macro matcher; matchers must be contained in balanced delimiters";
766         sess.span_diagnostic.span_err(lhs.span(), msg);
767         false
768     }
769     // we don't abort on errors on rejection, the driver will do that for us
770     // after parsing/expansion. we can report every error in every macro this way.
771 }
772
773 /// Checks that the lhs contains no repetition which could match an empty token
774 /// tree, because then the matcher would hang indefinitely.
775 fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[mbe::TokenTree]) -> bool {
776     use mbe::TokenTree;
777     for tt in tts {
778         match *tt {
779             TokenTree::Token(..)
780             | TokenTree::MetaVar(..)
781             | TokenTree::MetaVarDecl(..)
782             | TokenTree::MetaVarExpr(..) => (),
783             TokenTree::Delimited(_, ref del) => {
784                 if !check_lhs_no_empty_seq(sess, &del.tts) {
785                     return false;
786                 }
787             }
788             TokenTree::Sequence(span, ref seq) => {
789                 if seq.separator.is_none()
790                     && seq.tts.iter().all(|seq_tt| match *seq_tt {
791                         TokenTree::MetaVarDecl(_, _, Some(NonterminalKind::Vis)) => true,
792                         TokenTree::Sequence(_, ref sub_seq) => {
793                             sub_seq.kleene.op == mbe::KleeneOp::ZeroOrMore
794                                 || sub_seq.kleene.op == mbe::KleeneOp::ZeroOrOne
795                         }
796                         _ => false,
797                     })
798                 {
799                     let sp = span.entire();
800                     sess.span_diagnostic.span_err(sp, "repetition matches empty token tree");
801                     return false;
802                 }
803                 if !check_lhs_no_empty_seq(sess, &seq.tts) {
804                     return false;
805                 }
806             }
807         }
808     }
809
810     true
811 }
812
813 fn check_rhs(sess: &ParseSess, rhs: &mbe::TokenTree) -> bool {
814     match *rhs {
815         mbe::TokenTree::Delimited(..) => return true,
816         _ => {
817             sess.span_diagnostic.span_err(rhs.span(), "macro rhs must be delimited");
818         }
819     }
820     false
821 }
822
823 fn check_matcher(sess: &ParseSess, def: &ast::Item, matcher: &[mbe::TokenTree]) -> bool {
824     let first_sets = FirstSets::new(matcher);
825     let empty_suffix = TokenSet::empty();
826     let err = sess.span_diagnostic.err_count();
827     check_matcher_core(sess, def, &first_sets, matcher, &empty_suffix);
828     err == sess.span_diagnostic.err_count()
829 }
830
831 fn has_compile_error_macro(rhs: &mbe::TokenTree) -> bool {
832     match rhs {
833         mbe::TokenTree::Delimited(_sp, d) => {
834             let has_compile_error = d.tts.array_windows::<3>().any(|[ident, bang, args]| {
835                 if let mbe::TokenTree::Token(ident) = ident &&
836                         let TokenKind::Ident(ident, _) = ident.kind &&
837                         ident == sym::compile_error &&
838                         let mbe::TokenTree::Token(bang) = bang &&
839                         let TokenKind::Not = bang.kind &&
840                         let mbe::TokenTree::Delimited(_, del) = args &&
841                         del.delim != Delimiter::Invisible
842                     {
843                         true
844                     } else {
845                         false
846                     }
847             });
848             if has_compile_error { true } else { d.tts.iter().any(has_compile_error_macro) }
849         }
850         _ => false,
851     }
852 }
853
854 // `The FirstSets` for a matcher is a mapping from subsequences in the
855 // matcher to the FIRST set for that subsequence.
856 //
857 // This mapping is partially precomputed via a backwards scan over the
858 // token trees of the matcher, which provides a mapping from each
859 // repetition sequence to its *first* set.
860 //
861 // (Hypothetically, sequences should be uniquely identifiable via their
862 // spans, though perhaps that is false, e.g., for macro-generated macros
863 // that do not try to inject artificial span information. My plan is
864 // to try to catch such cases ahead of time and not include them in
865 // the precomputed mapping.)
866 struct FirstSets<'tt> {
867     // this maps each TokenTree::Sequence `$(tt ...) SEP OP` that is uniquely identified by its
868     // span in the original matcher to the First set for the inner sequence `tt ...`.
869     //
870     // If two sequences have the same span in a matcher, then map that
871     // span to None (invalidating the mapping here and forcing the code to
872     // use a slow path).
873     first: FxHashMap<Span, Option<TokenSet<'tt>>>,
874 }
875
876 impl<'tt> FirstSets<'tt> {
877     fn new(tts: &'tt [mbe::TokenTree]) -> FirstSets<'tt> {
878         use mbe::TokenTree;
879
880         let mut sets = FirstSets { first: FxHashMap::default() };
881         build_recur(&mut sets, tts);
882         return sets;
883
884         // walks backward over `tts`, returning the FIRST for `tts`
885         // and updating `sets` at the same time for all sequence
886         // substructure we find within `tts`.
887         fn build_recur<'tt>(sets: &mut FirstSets<'tt>, tts: &'tt [TokenTree]) -> TokenSet<'tt> {
888             let mut first = TokenSet::empty();
889             for tt in tts.iter().rev() {
890                 match *tt {
891                     TokenTree::Token(..)
892                     | TokenTree::MetaVar(..)
893                     | TokenTree::MetaVarDecl(..)
894                     | TokenTree::MetaVarExpr(..) => {
895                         first.replace_with(TtHandle::TtRef(tt));
896                     }
897                     TokenTree::Delimited(span, ref delimited) => {
898                         build_recur(sets, &delimited.tts);
899                         first.replace_with(TtHandle::from_token_kind(
900                             token::OpenDelim(delimited.delim),
901                             span.open,
902                         ));
903                     }
904                     TokenTree::Sequence(sp, ref seq_rep) => {
905                         let subfirst = build_recur(sets, &seq_rep.tts);
906
907                         match sets.first.entry(sp.entire()) {
908                             Entry::Vacant(vac) => {
909                                 vac.insert(Some(subfirst.clone()));
910                             }
911                             Entry::Occupied(mut occ) => {
912                                 // if there is already an entry, then a span must have collided.
913                                 // This should not happen with typical macro_rules macros,
914                                 // but syntax extensions need not maintain distinct spans,
915                                 // so distinct syntax trees can be assigned the same span.
916                                 // In such a case, the map cannot be trusted; so mark this
917                                 // entry as unusable.
918                                 occ.insert(None);
919                             }
920                         }
921
922                         // If the sequence contents can be empty, then the first
923                         // token could be the separator token itself.
924
925                         if let (Some(sep), true) = (&seq_rep.separator, subfirst.maybe_empty) {
926                             first.add_one_maybe(TtHandle::from_token(sep.clone()));
927                         }
928
929                         // Reverse scan: Sequence comes before `first`.
930                         if subfirst.maybe_empty
931                             || seq_rep.kleene.op == mbe::KleeneOp::ZeroOrMore
932                             || seq_rep.kleene.op == mbe::KleeneOp::ZeroOrOne
933                         {
934                             // If sequence is potentially empty, then
935                             // union them (preserving first emptiness).
936                             first.add_all(&TokenSet { maybe_empty: true, ..subfirst });
937                         } else {
938                             // Otherwise, sequence guaranteed
939                             // non-empty; replace first.
940                             first = subfirst;
941                         }
942                     }
943                 }
944             }
945
946             first
947         }
948     }
949
950     // walks forward over `tts` until all potential FIRST tokens are
951     // identified.
952     fn first(&self, tts: &'tt [mbe::TokenTree]) -> TokenSet<'tt> {
953         use mbe::TokenTree;
954
955         let mut first = TokenSet::empty();
956         for tt in tts.iter() {
957             assert!(first.maybe_empty);
958             match *tt {
959                 TokenTree::Token(..)
960                 | TokenTree::MetaVar(..)
961                 | TokenTree::MetaVarDecl(..)
962                 | TokenTree::MetaVarExpr(..) => {
963                     first.add_one(TtHandle::TtRef(tt));
964                     return first;
965                 }
966                 TokenTree::Delimited(span, ref delimited) => {
967                     first.add_one(TtHandle::from_token_kind(
968                         token::OpenDelim(delimited.delim),
969                         span.open,
970                     ));
971                     return first;
972                 }
973                 TokenTree::Sequence(sp, ref seq_rep) => {
974                     let subfirst_owned;
975                     let subfirst = match self.first.get(&sp.entire()) {
976                         Some(&Some(ref subfirst)) => subfirst,
977                         Some(&None) => {
978                             subfirst_owned = self.first(&seq_rep.tts);
979                             &subfirst_owned
980                         }
981                         None => {
982                             panic!("We missed a sequence during FirstSets construction");
983                         }
984                     };
985
986                     // If the sequence contents can be empty, then the first
987                     // token could be the separator token itself.
988                     if let (Some(sep), true) = (&seq_rep.separator, subfirst.maybe_empty) {
989                         first.add_one_maybe(TtHandle::from_token(sep.clone()));
990                     }
991
992                     assert!(first.maybe_empty);
993                     first.add_all(subfirst);
994                     if subfirst.maybe_empty
995                         || seq_rep.kleene.op == mbe::KleeneOp::ZeroOrMore
996                         || seq_rep.kleene.op == mbe::KleeneOp::ZeroOrOne
997                     {
998                         // Continue scanning for more first
999                         // tokens, but also make sure we
1000                         // restore empty-tracking state.
1001                         first.maybe_empty = true;
1002                         continue;
1003                     } else {
1004                         return first;
1005                     }
1006                 }
1007             }
1008         }
1009
1010         // we only exit the loop if `tts` was empty or if every
1011         // element of `tts` matches the empty sequence.
1012         assert!(first.maybe_empty);
1013         first
1014     }
1015 }
1016
1017 // Most `mbe::TokenTree`s are pre-existing in the matcher, but some are defined
1018 // implicitly, such as opening/closing delimiters and sequence repetition ops.
1019 // This type encapsulates both kinds. It implements `Clone` while avoiding the
1020 // need for `mbe::TokenTree` to implement `Clone`.
1021 #[derive(Debug)]
1022 enum TtHandle<'tt> {
1023     /// This is used in most cases.
1024     TtRef(&'tt mbe::TokenTree),
1025
1026     /// This is only used for implicit token trees. The `mbe::TokenTree` *must*
1027     /// be `mbe::TokenTree::Token`. No other variants are allowed. We store an
1028     /// `mbe::TokenTree` rather than a `Token` so that `get()` can return a
1029     /// `&mbe::TokenTree`.
1030     Token(mbe::TokenTree),
1031 }
1032
1033 impl<'tt> TtHandle<'tt> {
1034     fn from_token(tok: Token) -> Self {
1035         TtHandle::Token(mbe::TokenTree::Token(tok))
1036     }
1037
1038     fn from_token_kind(kind: TokenKind, span: Span) -> Self {
1039         TtHandle::from_token(Token::new(kind, span))
1040     }
1041
1042     // Get a reference to a token tree.
1043     fn get(&'tt self) -> &'tt mbe::TokenTree {
1044         match self {
1045             TtHandle::TtRef(tt) => tt,
1046             TtHandle::Token(token_tt) => &token_tt,
1047         }
1048     }
1049 }
1050
1051 impl<'tt> PartialEq for TtHandle<'tt> {
1052     fn eq(&self, other: &TtHandle<'tt>) -> bool {
1053         self.get() == other.get()
1054     }
1055 }
1056
1057 impl<'tt> Clone for TtHandle<'tt> {
1058     fn clone(&self) -> Self {
1059         match self {
1060             TtHandle::TtRef(tt) => TtHandle::TtRef(tt),
1061
1062             // This variant *must* contain a `mbe::TokenTree::Token`, and not
1063             // any other variant of `mbe::TokenTree`.
1064             TtHandle::Token(mbe::TokenTree::Token(tok)) => {
1065                 TtHandle::Token(mbe::TokenTree::Token(tok.clone()))
1066             }
1067
1068             _ => unreachable!(),
1069         }
1070     }
1071 }
1072
1073 // A set of `mbe::TokenTree`s, which may include `TokenTree::Match`s
1074 // (for macro-by-example syntactic variables). It also carries the
1075 // `maybe_empty` flag; that is true if and only if the matcher can
1076 // match an empty token sequence.
1077 //
1078 // The First set is computed on submatchers like `$($a:expr b),* $(c)* d`,
1079 // which has corresponding FIRST = {$a:expr, c, d}.
1080 // Likewise, `$($a:expr b),* $(c)+ d` has FIRST = {$a:expr, c}.
1081 //
1082 // (Notably, we must allow for *-op to occur zero times.)
1083 #[derive(Clone, Debug)]
1084 struct TokenSet<'tt> {
1085     tokens: Vec<TtHandle<'tt>>,
1086     maybe_empty: bool,
1087 }
1088
1089 impl<'tt> TokenSet<'tt> {
1090     // Returns a set for the empty sequence.
1091     fn empty() -> Self {
1092         TokenSet { tokens: Vec::new(), maybe_empty: true }
1093     }
1094
1095     // Returns the set `{ tok }` for the single-token (and thus
1096     // non-empty) sequence [tok].
1097     fn singleton(tt: TtHandle<'tt>) -> Self {
1098         TokenSet { tokens: vec![tt], maybe_empty: false }
1099     }
1100
1101     // Changes self to be the set `{ tok }`.
1102     // Since `tok` is always present, marks self as non-empty.
1103     fn replace_with(&mut self, tt: TtHandle<'tt>) {
1104         self.tokens.clear();
1105         self.tokens.push(tt);
1106         self.maybe_empty = false;
1107     }
1108
1109     // Changes self to be the empty set `{}`; meant for use when
1110     // the particular token does not matter, but we want to
1111     // record that it occurs.
1112     fn replace_with_irrelevant(&mut self) {
1113         self.tokens.clear();
1114         self.maybe_empty = false;
1115     }
1116
1117     // Adds `tok` to the set for `self`, marking sequence as non-empty.
1118     fn add_one(&mut self, tt: TtHandle<'tt>) {
1119         if !self.tokens.contains(&tt) {
1120             self.tokens.push(tt);
1121         }
1122         self.maybe_empty = false;
1123     }
1124
1125     // Adds `tok` to the set for `self`. (Leaves `maybe_empty` flag alone.)
1126     fn add_one_maybe(&mut self, tt: TtHandle<'tt>) {
1127         if !self.tokens.contains(&tt) {
1128             self.tokens.push(tt);
1129         }
1130     }
1131
1132     // Adds all elements of `other` to this.
1133     //
1134     // (Since this is a set, we filter out duplicates.)
1135     //
1136     // If `other` is potentially empty, then preserves the previous
1137     // setting of the empty flag of `self`. If `other` is guaranteed
1138     // non-empty, then `self` is marked non-empty.
1139     fn add_all(&mut self, other: &Self) {
1140         for tt in &other.tokens {
1141             if !self.tokens.contains(tt) {
1142                 self.tokens.push(tt.clone());
1143             }
1144         }
1145         if !other.maybe_empty {
1146             self.maybe_empty = false;
1147         }
1148     }
1149 }
1150
1151 // Checks that `matcher` is internally consistent and that it
1152 // can legally be followed by a token `N`, for all `N` in `follow`.
1153 // (If `follow` is empty, then it imposes no constraint on
1154 // the `matcher`.)
1155 //
1156 // Returns the set of NT tokens that could possibly come last in
1157 // `matcher`. (If `matcher` matches the empty sequence, then
1158 // `maybe_empty` will be set to true.)
1159 //
1160 // Requires that `first_sets` is pre-computed for `matcher`;
1161 // see `FirstSets::new`.
1162 fn check_matcher_core<'tt>(
1163     sess: &ParseSess,
1164     def: &ast::Item,
1165     first_sets: &FirstSets<'tt>,
1166     matcher: &'tt [mbe::TokenTree],
1167     follow: &TokenSet<'tt>,
1168 ) -> TokenSet<'tt> {
1169     use mbe::TokenTree;
1170
1171     let mut last = TokenSet::empty();
1172
1173     // 2. For each token and suffix  [T, SUFFIX] in M:
1174     // ensure that T can be followed by SUFFIX, and if SUFFIX may be empty,
1175     // then ensure T can also be followed by any element of FOLLOW.
1176     'each_token: for i in 0..matcher.len() {
1177         let token = &matcher[i];
1178         let suffix = &matcher[i + 1..];
1179
1180         let build_suffix_first = || {
1181             let mut s = first_sets.first(suffix);
1182             if s.maybe_empty {
1183                 s.add_all(follow);
1184             }
1185             s
1186         };
1187
1188         // (we build `suffix_first` on demand below; you can tell
1189         // which cases are supposed to fall through by looking for the
1190         // initialization of this variable.)
1191         let suffix_first;
1192
1193         // First, update `last` so that it corresponds to the set
1194         // of NT tokens that might end the sequence `... token`.
1195         match *token {
1196             TokenTree::Token(..)
1197             | TokenTree::MetaVar(..)
1198             | TokenTree::MetaVarDecl(..)
1199             | TokenTree::MetaVarExpr(..) => {
1200                 if token_can_be_followed_by_any(token) {
1201                     // don't need to track tokens that work with any,
1202                     last.replace_with_irrelevant();
1203                     // ... and don't need to check tokens that can be
1204                     // followed by anything against SUFFIX.
1205                     continue 'each_token;
1206                 } else {
1207                     last.replace_with(TtHandle::TtRef(token));
1208                     suffix_first = build_suffix_first();
1209                 }
1210             }
1211             TokenTree::Delimited(span, ref d) => {
1212                 let my_suffix = TokenSet::singleton(TtHandle::from_token_kind(
1213                     token::CloseDelim(d.delim),
1214                     span.close,
1215                 ));
1216                 check_matcher_core(sess, def, first_sets, &d.tts, &my_suffix);
1217                 // don't track non NT tokens
1218                 last.replace_with_irrelevant();
1219
1220                 // also, we don't need to check delimited sequences
1221                 // against SUFFIX
1222                 continue 'each_token;
1223             }
1224             TokenTree::Sequence(_, ref seq_rep) => {
1225                 suffix_first = build_suffix_first();
1226                 // The trick here: when we check the interior, we want
1227                 // to include the separator (if any) as a potential
1228                 // (but not guaranteed) element of FOLLOW. So in that
1229                 // case, we make a temp copy of suffix and stuff
1230                 // delimiter in there.
1231                 //
1232                 // FIXME: Should I first scan suffix_first to see if
1233                 // delimiter is already in it before I go through the
1234                 // work of cloning it? But then again, this way I may
1235                 // get a "tighter" span?
1236                 let mut new;
1237                 let my_suffix = if let Some(sep) = &seq_rep.separator {
1238                     new = suffix_first.clone();
1239                     new.add_one_maybe(TtHandle::from_token(sep.clone()));
1240                     &new
1241                 } else {
1242                     &suffix_first
1243                 };
1244
1245                 // At this point, `suffix_first` is built, and
1246                 // `my_suffix` is some TokenSet that we can use
1247                 // for checking the interior of `seq_rep`.
1248                 let next = check_matcher_core(sess, def, first_sets, &seq_rep.tts, my_suffix);
1249                 if next.maybe_empty {
1250                     last.add_all(&next);
1251                 } else {
1252                     last = next;
1253                 }
1254
1255                 // the recursive call to check_matcher_core already ran the 'each_last
1256                 // check below, so we can just keep going forward here.
1257                 continue 'each_token;
1258             }
1259         }
1260
1261         // (`suffix_first` guaranteed initialized once reaching here.)
1262
1263         // Now `last` holds the complete set of NT tokens that could
1264         // end the sequence before SUFFIX. Check that every one works with `suffix`.
1265         for tt in &last.tokens {
1266             if let &TokenTree::MetaVarDecl(span, name, Some(kind)) = tt.get() {
1267                 for next_token in &suffix_first.tokens {
1268                     let next_token = next_token.get();
1269
1270                     // Check if the old pat is used and the next token is `|`
1271                     // to warn about incompatibility with Rust 2021.
1272                     // We only emit this lint if we're parsing the original
1273                     // definition of this macro_rules, not while (re)parsing
1274                     // the macro when compiling another crate that is using the
1275                     // macro. (See #86567.)
1276                     // Macros defined in the current crate have a real node id,
1277                     // whereas macros from an external crate have a dummy id.
1278                     if def.id != DUMMY_NODE_ID
1279                         && matches!(kind, NonterminalKind::PatParam { inferred: true })
1280                         && matches!(next_token, TokenTree::Token(token) if token.kind == BinOp(token::BinOpToken::Or))
1281                     {
1282                         // It is suggestion to use pat_param, for example: $x:pat -> $x:pat_param.
1283                         let suggestion = quoted_tt_to_string(&TokenTree::MetaVarDecl(
1284                             span,
1285                             name,
1286                             Some(NonterminalKind::PatParam { inferred: false }),
1287                         ));
1288                         sess.buffer_lint_with_diagnostic(
1289                             &RUST_2021_INCOMPATIBLE_OR_PATTERNS,
1290                             span,
1291                             ast::CRATE_NODE_ID,
1292                             "the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro",
1293                             BuiltinLintDiagnostics::OrPatternsBackCompat(span, suggestion),
1294                         );
1295                     }
1296                     match is_in_follow(next_token, kind) {
1297                         IsInFollow::Yes => {}
1298                         IsInFollow::No(possible) => {
1299                             let may_be = if last.tokens.len() == 1 && suffix_first.tokens.len() == 1
1300                             {
1301                                 "is"
1302                             } else {
1303                                 "may be"
1304                             };
1305
1306                             let sp = next_token.span();
1307                             let mut err = sess.span_diagnostic.struct_span_err(
1308                                 sp,
1309                                 &format!(
1310                                     "`${name}:{frag}` {may_be} followed by `{next}`, which \
1311                                      is not allowed for `{frag}` fragments",
1312                                     name = name,
1313                                     frag = kind,
1314                                     next = quoted_tt_to_string(next_token),
1315                                     may_be = may_be
1316                                 ),
1317                             );
1318                             err.span_label(sp, format!("not allowed after `{}` fragments", kind));
1319
1320                             if kind == NonterminalKind::PatWithOr
1321                                 && sess.edition.rust_2021()
1322                                 && next_token.is_token(&BinOp(token::BinOpToken::Or))
1323                             {
1324                                 let suggestion = quoted_tt_to_string(&TokenTree::MetaVarDecl(
1325                                     span,
1326                                     name,
1327                                     Some(NonterminalKind::PatParam { inferred: false }),
1328                                 ));
1329                                 err.span_suggestion(
1330                                     span,
1331                                     "try a `pat_param` fragment specifier instead",
1332                                     suggestion,
1333                                     Applicability::MaybeIncorrect,
1334                                 );
1335                             }
1336
1337                             let msg = "allowed there are: ";
1338                             match possible {
1339                                 &[] => {}
1340                                 &[t] => {
1341                                     err.note(&format!(
1342                                         "only {} is allowed after `{}` fragments",
1343                                         t, kind,
1344                                     ));
1345                                 }
1346                                 ts => {
1347                                     err.note(&format!(
1348                                         "{}{} or {}",
1349                                         msg,
1350                                         ts[..ts.len() - 1]
1351                                             .iter()
1352                                             .copied()
1353                                             .collect::<Vec<_>>()
1354                                             .join(", "),
1355                                         ts[ts.len() - 1],
1356                                     ));
1357                                 }
1358                             }
1359                             err.emit();
1360                         }
1361                     }
1362                 }
1363             }
1364         }
1365     }
1366     last
1367 }
1368
1369 fn token_can_be_followed_by_any(tok: &mbe::TokenTree) -> bool {
1370     if let mbe::TokenTree::MetaVarDecl(_, _, Some(kind)) = *tok {
1371         frag_can_be_followed_by_any(kind)
1372     } else {
1373         // (Non NT's can always be followed by anything in matchers.)
1374         true
1375     }
1376 }
1377
1378 /// Returns `true` if a fragment of type `frag` can be followed by any sort of
1379 /// token. We use this (among other things) as a useful approximation
1380 /// for when `frag` can be followed by a repetition like `$(...)*` or
1381 /// `$(...)+`. In general, these can be a bit tricky to reason about,
1382 /// so we adopt a conservative position that says that any fragment
1383 /// specifier which consumes at most one token tree can be followed by
1384 /// a fragment specifier (indeed, these fragments can be followed by
1385 /// ANYTHING without fear of future compatibility hazards).
1386 fn frag_can_be_followed_by_any(kind: NonterminalKind) -> bool {
1387     matches!(
1388         kind,
1389         NonterminalKind::Item           // always terminated by `}` or `;`
1390         | NonterminalKind::Block        // exactly one token tree
1391         | NonterminalKind::Ident        // exactly one token tree
1392         | NonterminalKind::Literal      // exactly one token tree
1393         | NonterminalKind::Meta         // exactly one token tree
1394         | NonterminalKind::Lifetime     // exactly one token tree
1395         | NonterminalKind::TT // exactly one token tree
1396     )
1397 }
1398
1399 enum IsInFollow {
1400     Yes,
1401     No(&'static [&'static str]),
1402 }
1403
1404 /// Returns `true` if `frag` can legally be followed by the token `tok`. For
1405 /// fragments that can consume an unbounded number of tokens, `tok`
1406 /// must be within a well-defined follow set. This is intended to
1407 /// guarantee future compatibility: for example, without this rule, if
1408 /// we expanded `expr` to include a new binary operator, we might
1409 /// break macros that were relying on that binary operator as a
1410 /// separator.
1411 // when changing this do not forget to update doc/book/macros.md!
1412 fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow {
1413     use mbe::TokenTree;
1414
1415     if let TokenTree::Token(Token { kind: token::CloseDelim(_), .. }) = *tok {
1416         // closing a token tree can never be matched by any fragment;
1417         // iow, we always require that `(` and `)` match, etc.
1418         IsInFollow::Yes
1419     } else {
1420         match kind {
1421             NonterminalKind::Item => {
1422                 // since items *must* be followed by either a `;` or a `}`, we can
1423                 // accept anything after them
1424                 IsInFollow::Yes
1425             }
1426             NonterminalKind::Block => {
1427                 // anything can follow block, the braces provide an easy boundary to
1428                 // maintain
1429                 IsInFollow::Yes
1430             }
1431             NonterminalKind::Stmt | NonterminalKind::Expr => {
1432                 const TOKENS: &[&str] = &["`=>`", "`,`", "`;`"];
1433                 match tok {
1434                     TokenTree::Token(token) => match token.kind {
1435                         FatArrow | Comma | Semi => IsInFollow::Yes,
1436                         _ => IsInFollow::No(TOKENS),
1437                     },
1438                     _ => IsInFollow::No(TOKENS),
1439                 }
1440             }
1441             NonterminalKind::PatParam { .. } => {
1442                 const TOKENS: &[&str] = &["`=>`", "`,`", "`=`", "`|`", "`if`", "`in`"];
1443                 match tok {
1444                     TokenTree::Token(token) => match token.kind {
1445                         FatArrow | Comma | Eq | BinOp(token::Or) => IsInFollow::Yes,
1446                         Ident(name, false) if name == kw::If || name == kw::In => IsInFollow::Yes,
1447                         _ => IsInFollow::No(TOKENS),
1448                     },
1449                     _ => IsInFollow::No(TOKENS),
1450                 }
1451             }
1452             NonterminalKind::PatWithOr { .. } => {
1453                 const TOKENS: &[&str] = &["`=>`", "`,`", "`=`", "`if`", "`in`"];
1454                 match tok {
1455                     TokenTree::Token(token) => match token.kind {
1456                         FatArrow | Comma | Eq => IsInFollow::Yes,
1457                         Ident(name, false) if name == kw::If || name == kw::In => IsInFollow::Yes,
1458                         _ => IsInFollow::No(TOKENS),
1459                     },
1460                     _ => IsInFollow::No(TOKENS),
1461                 }
1462             }
1463             NonterminalKind::Path | NonterminalKind::Ty => {
1464                 const TOKENS: &[&str] = &[
1465                     "`{`", "`[`", "`=>`", "`,`", "`>`", "`=`", "`:`", "`;`", "`|`", "`as`",
1466                     "`where`",
1467                 ];
1468                 match tok {
1469                     TokenTree::Token(token) => match token.kind {
1470                         OpenDelim(Delimiter::Brace)
1471                         | OpenDelim(Delimiter::Bracket)
1472                         | Comma
1473                         | FatArrow
1474                         | Colon
1475                         | Eq
1476                         | Gt
1477                         | BinOp(token::Shr)
1478                         | Semi
1479                         | BinOp(token::Or) => IsInFollow::Yes,
1480                         Ident(name, false) if name == kw::As || name == kw::Where => {
1481                             IsInFollow::Yes
1482                         }
1483                         _ => IsInFollow::No(TOKENS),
1484                     },
1485                     TokenTree::MetaVarDecl(_, _, Some(NonterminalKind::Block)) => IsInFollow::Yes,
1486                     _ => IsInFollow::No(TOKENS),
1487                 }
1488             }
1489             NonterminalKind::Ident | NonterminalKind::Lifetime => {
1490                 // being a single token, idents and lifetimes are harmless
1491                 IsInFollow::Yes
1492             }
1493             NonterminalKind::Literal => {
1494                 // literals may be of a single token, or two tokens (negative numbers)
1495                 IsInFollow::Yes
1496             }
1497             NonterminalKind::Meta | NonterminalKind::TT => {
1498                 // being either a single token or a delimited sequence, tt is
1499                 // harmless
1500                 IsInFollow::Yes
1501             }
1502             NonterminalKind::Vis => {
1503                 // Explicitly disallow `priv`, on the off chance it comes back.
1504                 const TOKENS: &[&str] = &["`,`", "an ident", "a type"];
1505                 match tok {
1506                     TokenTree::Token(token) => match token.kind {
1507                         Comma => IsInFollow::Yes,
1508                         Ident(name, is_raw) if is_raw || name != kw::Priv => IsInFollow::Yes,
1509                         _ => {
1510                             if token.can_begin_type() {
1511                                 IsInFollow::Yes
1512                             } else {
1513                                 IsInFollow::No(TOKENS)
1514                             }
1515                         }
1516                     },
1517                     TokenTree::MetaVarDecl(
1518                         _,
1519                         _,
1520                         Some(NonterminalKind::Ident | NonterminalKind::Ty | NonterminalKind::Path),
1521                     ) => IsInFollow::Yes,
1522                     _ => IsInFollow::No(TOKENS),
1523                 }
1524             }
1525         }
1526     }
1527 }
1528
1529 fn quoted_tt_to_string(tt: &mbe::TokenTree) -> String {
1530     match *tt {
1531         mbe::TokenTree::Token(ref token) => pprust::token_to_string(&token).into(),
1532         mbe::TokenTree::MetaVar(_, name) => format!("${}", name),
1533         mbe::TokenTree::MetaVarDecl(_, name, Some(kind)) => format!("${}:{}", name, kind),
1534         mbe::TokenTree::MetaVarDecl(_, name, None) => format!("${}:", name),
1535         _ => panic!(
1536             "{}",
1537             "unexpected mbe::TokenTree::{Sequence or Delimited} \
1538              in follow set checker"
1539         ),
1540     }
1541 }
1542
1543 fn parser_from_cx(sess: &ParseSess, tts: TokenStream) -> Parser<'_> {
1544     Parser::new(sess, tts, true, rustc_parse::MACRO_ARGUMENTS)
1545 }
1546
1547 /// Generates an appropriate parsing failure message. For EOF, this is "unexpected end...". For
1548 /// other tokens, this is "unexpected token...".
1549 fn parse_failure_msg(tok: &Token) -> String {
1550     match tok.kind {
1551         token::Eof => "unexpected end of macro invocation".to_string(),
1552         _ => format!("no rules expected the token `{}`", pprust::token_to_string(tok),),
1553     }
1554 }