]> git.lizzy.rs Git - rust.git/blob - src/librustc_expand/mbe/macro_rules.rs
9e6edee265c989261b17f0049ac7157171e5597c
[rust.git] / src / librustc_expand / mbe / macro_rules.rs
1 use crate::base::{DummyResult, ExpansionData, 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::parse_tt;
7 use crate::mbe::macro_parser::{Error, Failure, Success};
8 use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq};
9 use crate::mbe::transcribe::transcribe;
10
11 use rustc_ast_pretty::pprust;
12 use rustc_attr::{self as attr, TransparencyError};
13 use rustc_data_structures::fx::FxHashMap;
14 use rustc_data_structures::sync::Lrc;
15 use rustc_errors::{Applicability, DiagnosticBuilder, FatalError};
16 use rustc_feature::Features;
17 use rustc_parse::parser::Parser;
18 use rustc_parse::Directory;
19 use rustc_session::parse::ParseSess;
20 use rustc_span::edition::Edition;
21 use rustc_span::hygiene::Transparency;
22 use rustc_span::symbol::{kw, sym, Symbol};
23 use rustc_span::Span;
24 use syntax::ast;
25 use syntax::token::{self, NtTT, Token, TokenKind::*};
26 use syntax::tokenstream::{DelimSpan, TokenStream};
27
28 use log::debug;
29 use std::borrow::Cow;
30 use std::collections::hash_map::Entry;
31 use std::{mem, slice};
32
33 const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \
34                                         `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, \
35                                         `literal`, `path`, `meta`, `tt`, `item` and `vis`";
36
37 crate struct ParserAnyMacro<'a> {
38     parser: Parser<'a>,
39
40     /// Span of the expansion site of the macro this parser is for
41     site_span: Span,
42     /// The ident of the macro we're parsing
43     macro_ident: ast::Ident,
44     arm_span: Span,
45 }
46
47 crate fn annotate_err_with_kind(
48     err: &mut DiagnosticBuilder<'_>,
49     kind: AstFragmentKind,
50     span: Span,
51 ) {
52     match kind {
53         AstFragmentKind::Ty => {
54             err.span_label(span, "this macro call doesn't expand to a type");
55         }
56         AstFragmentKind::Pat => {
57             err.span_label(span, "this macro call doesn't expand to a pattern");
58         }
59         _ => {}
60     };
61 }
62
63 /// Instead of e.g. `vec![a, b, c]` in a pattern context, suggest `[a, b, c]`.
64 fn suggest_slice_pat(e: &mut DiagnosticBuilder<'_>, site_span: Span, parser: &Parser<'_>) {
65     let mut suggestion = None;
66     if let Ok(code) = parser.sess.source_map().span_to_snippet(site_span) {
67         if let Some(bang) = code.find('!') {
68             suggestion = Some(code[bang + 1..].to_string());
69         }
70     }
71     if let Some(suggestion) = suggestion {
72         e.span_suggestion(
73             site_span,
74             "use a slice pattern here instead",
75             suggestion,
76             Applicability::MachineApplicable,
77         );
78     } else {
79         e.span_label(site_span, "use a slice pattern here instead");
80     }
81     e.help(
82         "for more information, see https://doc.rust-lang.org/edition-guide/\
83         rust-2018/slice-patterns.html",
84     );
85 }
86
87 impl<'a> ParserAnyMacro<'a> {
88     crate fn make(mut self: Box<ParserAnyMacro<'a>>, kind: AstFragmentKind) -> AstFragment {
89         let ParserAnyMacro { site_span, macro_ident, ref mut parser, arm_span } = *self;
90         let fragment = panictry!(parse_ast_fragment(parser, kind, true).map_err(|mut e| {
91             if parser.token == token::Eof && e.message().ends_with(", found `<eof>`") {
92                 if !e.span.is_dummy() {
93                     // early end of macro arm (#52866)
94                     e.replace_span_with(parser.sess.source_map().next_point(parser.token.span));
95                 }
96                 let msg = &e.message[0];
97                 e.message[0] = (
98                     format!(
99                         "macro expansion ends with an incomplete expression: {}",
100                         msg.0.replace(", found `<eof>`", ""),
101                     ),
102                     msg.1,
103                 );
104             }
105             if e.span.is_dummy() {
106                 // Get around lack of span in error (#30128)
107                 e.replace_span_with(site_span);
108                 if parser.sess.source_map().span_to_filename(arm_span).is_real() {
109                     e.span_label(arm_span, "in this macro arm");
110                 }
111             } else if !parser.sess.source_map().span_to_filename(parser.token.span).is_real() {
112                 e.span_label(site_span, "in this macro invocation");
113             }
114             match kind {
115                 AstFragmentKind::Pat if macro_ident.name == sym::vec => {
116                     suggest_slice_pat(&mut e, site_span, parser);
117                 }
118                 _ => annotate_err_with_kind(&mut e, kind, site_span),
119             };
120             e
121         }));
122
123         // We allow semicolons at the end of expressions -- e.g., the semicolon in
124         // `macro_rules! m { () => { panic!(); } }` isn't parsed by `.parse_expr()`,
125         // but `m!()` is allowed in expression positions (cf. issue #34706).
126         if kind == AstFragmentKind::Expr && parser.token == token::Semi {
127             parser.bump();
128         }
129
130         // Make sure we don't have any tokens left to parse so we don't silently drop anything.
131         let path = ast::Path::from_ident(macro_ident.with_span_pos(site_span));
132         ensure_complete_parse(parser, &path, kind.name(), site_span);
133         fragment
134     }
135 }
136
137 struct MacroRulesMacroExpander {
138     name: ast::Ident,
139     span: Span,
140     transparency: Transparency,
141     lhses: Vec<mbe::TokenTree>,
142     rhses: Vec<mbe::TokenTree>,
143     valid: bool,
144 }
145
146 impl TTMacroExpander for MacroRulesMacroExpander {
147     fn expand<'cx>(
148         &self,
149         cx: &'cx mut ExtCtxt<'_>,
150         sp: Span,
151         input: TokenStream,
152     ) -> Box<dyn MacResult + 'cx> {
153         if !self.valid {
154             return DummyResult::any(sp);
155         }
156         generic_extension(
157             cx,
158             sp,
159             self.span,
160             self.name,
161             self.transparency,
162             input,
163             &self.lhses,
164             &self.rhses,
165         )
166     }
167 }
168
169 fn trace_macros_note(cx_expansions: &mut FxHashMap<Span, Vec<String>>, sp: Span, message: String) {
170     let sp = sp.macro_backtrace().last().map(|trace| trace.call_site).unwrap_or(sp);
171     cx_expansions.entry(sp).or_default().push(message);
172 }
173
174 /// Given `lhses` and `rhses`, this is the new macro we create
175 fn generic_extension<'cx>(
176     cx: &'cx mut ExtCtxt<'_>,
177     sp: Span,
178     def_span: Span,
179     name: ast::Ident,
180     transparency: Transparency,
181     arg: TokenStream,
182     lhses: &[mbe::TokenTree],
183     rhses: &[mbe::TokenTree],
184 ) -> Box<dyn MacResult + 'cx> {
185     if cx.trace_macros() {
186         let msg = format!("expanding `{}! {{ {} }}`", name, pprust::tts_to_string(arg.clone()));
187         trace_macros_note(&mut cx.expansions, sp, msg);
188     }
189
190     // Which arm's failure should we report? (the one furthest along)
191     let mut best_failure: Option<(Token, &str)> = None;
192
193     // We create a base parser that can be used for the "black box" parts.
194     // Every iteration needs a fresh copy of that base parser. However, the
195     // parser is not mutated on many of the iterations, particularly when
196     // dealing with macros like this:
197     //
198     // macro_rules! foo {
199     //     ("a") => (A);
200     //     ("b") => (B);
201     //     ("c") => (C);
202     //     // ... etc. (maybe hundreds more)
203     // }
204     //
205     // as seen in the `html5ever` benchmark. We use a `Cow` so that the base
206     // parser is only cloned when necessary (upon mutation). Furthermore, we
207     // reinitialize the `Cow` with the base parser at the start of every
208     // iteration, so that any mutated parsers are not reused. This is all quite
209     // hacky, but speeds up the `html5ever` benchmark significantly. (Issue
210     // 68836 suggests a more comprehensive but more complex change to deal with
211     // this situation.)
212     let base_parser = base_parser_from_cx(&cx.current_expansion, &cx.parse_sess, arg.clone());
213
214     for (i, lhs) in lhses.iter().enumerate() {
215         let mut parser = Cow::Borrowed(&base_parser);
216
217         // try each arm's matchers
218         let lhs_tt = match *lhs {
219             mbe::TokenTree::Delimited(_, ref delim) => &delim.tts[..],
220             _ => cx.span_bug(sp, "malformed macro lhs"),
221         };
222
223         // Take a snapshot of the state of pre-expansion gating at this point.
224         // This is used so that if a matcher is not `Success(..)`ful,
225         // then the spans which became gated when parsing the unsuccessful matcher
226         // are not recorded. On the first `Success(..)`ful matcher, the spans are merged.
227         let mut gated_spans_snaphot = mem::take(&mut *cx.parse_sess.gated_spans.spans.borrow_mut());
228
229         match parse_tt(&mut parser, lhs_tt) {
230             Success(named_matches) => {
231                 // The matcher was `Success(..)`ful.
232                 // Merge the gated spans from parsing the matcher with the pre-existing ones.
233                 cx.parse_sess.gated_spans.merge(gated_spans_snaphot);
234
235                 let rhs = match rhses[i] {
236                     // ignore delimiters
237                     mbe::TokenTree::Delimited(_, ref delimed) => delimed.tts.clone(),
238                     _ => cx.span_bug(sp, "malformed macro rhs"),
239                 };
240                 let arm_span = rhses[i].span();
241
242                 let rhs_spans = rhs.iter().map(|t| t.span()).collect::<Vec<_>>();
243                 // rhs has holes ( `$id` and `$(...)` that need filled)
244                 let mut tts = transcribe(cx, &named_matches, rhs, transparency);
245
246                 // Replace all the tokens for the corresponding positions in the macro, to maintain
247                 // proper positions in error reporting, while maintaining the macro_backtrace.
248                 if rhs_spans.len() == tts.len() {
249                     tts = tts.map_enumerated(|i, mut tt| {
250                         let mut sp = rhs_spans[i];
251                         sp = sp.with_ctxt(tt.span().ctxt());
252                         tt.set_span(sp);
253                         tt
254                     });
255                 }
256
257                 if cx.trace_macros() {
258                     let msg = format!("to `{}`", pprust::tts_to_string(tts.clone()));
259                     trace_macros_note(&mut cx.expansions, sp, msg);
260                 }
261
262                 let directory = Directory {
263                     path: cx.current_expansion.module.directory.clone(),
264                     ownership: cx.current_expansion.directory_ownership,
265                 };
266                 let mut p = Parser::new(cx.parse_sess(), tts, Some(directory), true, false, None);
267                 p.root_module_name =
268                     cx.current_expansion.module.mod_path.last().map(|id| id.to_string());
269                 p.last_type_ascription = cx.current_expansion.prior_type_ascription;
270
271                 p.process_potential_macro_variable();
272                 // Let the context choose how to interpret the result.
273                 // Weird, but useful for X-macros.
274                 return Box::new(ParserAnyMacro {
275                     parser: p,
276
277                     // Pass along the original expansion site and the name of the macro
278                     // so we can print a useful error message if the parse of the expanded
279                     // macro leaves unparsed tokens.
280                     site_span: sp,
281                     macro_ident: name,
282                     arm_span,
283                 });
284             }
285             Failure(token, msg) => match best_failure {
286                 Some((ref best_token, _)) if best_token.span.lo() >= token.span.lo() => {}
287                 _ => best_failure = Some((token, msg)),
288             },
289             Error(err_sp, ref msg) => cx.span_fatal(err_sp.substitute_dummy(sp), &msg[..]),
290         }
291
292         // The matcher was not `Success(..)`ful.
293         // Restore to the state before snapshotting and maybe try again.
294         mem::swap(&mut gated_spans_snaphot, &mut cx.parse_sess.gated_spans.spans.borrow_mut());
295     }
296     drop(base_parser);
297
298     let (token, label) = best_failure.expect("ran no matchers");
299     let span = token.span.substitute_dummy(sp);
300     let mut err = cx.struct_span_err(span, &parse_failure_msg(&token));
301     err.span_label(span, label);
302     if !def_span.is_dummy() && cx.source_map().span_to_filename(def_span).is_real() {
303         err.span_label(cx.source_map().def_span(def_span), "when calling this macro");
304     }
305
306     // Check whether there's a missing comma in this macro call, like `println!("{}" a);`
307     if let Some((arg, comma_span)) = arg.add_comma() {
308         for lhs in lhses {
309             // try each arm's matchers
310             let lhs_tt = match *lhs {
311                 mbe::TokenTree::Delimited(_, ref delim) => &delim.tts[..],
312                 _ => continue,
313             };
314             let base_parser =
315                 base_parser_from_cx(&cx.current_expansion, &cx.parse_sess, arg.clone());
316             match parse_tt(&mut Cow::Borrowed(&base_parser), lhs_tt) {
317                 Success(_) => {
318                     if comma_span.is_dummy() {
319                         err.note("you might be missing a comma");
320                     } else {
321                         err.span_suggestion_short(
322                             comma_span,
323                             "missing comma here",
324                             ", ".to_string(),
325                             Applicability::MachineApplicable,
326                         );
327                     }
328                 }
329                 _ => {}
330             }
331         }
332     }
333     err.emit();
334     cx.trace_macros_diag();
335     DummyResult::any(sp)
336 }
337
338 // Note that macro-by-example's input is also matched against a token tree:
339 //                   $( $lhs:tt => $rhs:tt );+
340 //
341 // Holy self-referential!
342
343 /// Converts a macro item into a syntax extension.
344 pub fn compile_declarative_macro(
345     sess: &ParseSess,
346     features: &Features,
347     def: &ast::Item,
348     edition: Edition,
349 ) -> SyntaxExtension {
350     let diag = &sess.span_diagnostic;
351     let lhs_nm = ast::Ident::new(sym::lhs, def.span);
352     let rhs_nm = ast::Ident::new(sym::rhs, def.span);
353     let tt_spec = ast::Ident::new(sym::tt, def.span);
354
355     // Parse the macro_rules! invocation
356     let (is_legacy, body) = match &def.kind {
357         ast::ItemKind::MacroDef(macro_def) => (macro_def.legacy, macro_def.body.inner_tokens()),
358         _ => unreachable!(),
359     };
360
361     // The pattern that macro_rules matches.
362     // The grammar for macro_rules! is:
363     // $( $lhs:tt => $rhs:tt );+
364     // ...quasiquoting this would be nice.
365     // These spans won't matter, anyways
366     let argument_gram = vec![
367         mbe::TokenTree::Sequence(
368             DelimSpan::dummy(),
369             Lrc::new(mbe::SequenceRepetition {
370                 tts: vec![
371                     mbe::TokenTree::MetaVarDecl(def.span, lhs_nm, tt_spec),
372                     mbe::TokenTree::token(token::FatArrow, def.span),
373                     mbe::TokenTree::MetaVarDecl(def.span, rhs_nm, tt_spec),
374                 ],
375                 separator: Some(Token::new(
376                     if is_legacy { token::Semi } else { token::Comma },
377                     def.span,
378                 )),
379                 kleene: mbe::KleeneToken::new(mbe::KleeneOp::OneOrMore, def.span),
380                 num_captures: 2,
381             }),
382         ),
383         // to phase into semicolon-termination instead of semicolon-separation
384         mbe::TokenTree::Sequence(
385             DelimSpan::dummy(),
386             Lrc::new(mbe::SequenceRepetition {
387                 tts: vec![mbe::TokenTree::token(
388                     if is_legacy { token::Semi } else { token::Comma },
389                     def.span,
390                 )],
391                 separator: None,
392                 kleene: mbe::KleeneToken::new(mbe::KleeneOp::ZeroOrMore, def.span),
393                 num_captures: 0,
394             }),
395         ),
396     ];
397
398     let base_parser = Parser::new(sess, body, None, true, true, rustc_parse::MACRO_ARGUMENTS);
399     let argument_map = match parse_tt(&mut Cow::Borrowed(&base_parser), &argument_gram) {
400         Success(m) => m,
401         Failure(token, msg) => {
402             let s = parse_failure_msg(&token);
403             let sp = token.span.substitute_dummy(def.span);
404             let mut err = sess.span_diagnostic.struct_span_fatal(sp, &s);
405             err.span_label(sp, msg);
406             err.emit();
407             FatalError.raise();
408         }
409         Error(sp, s) => {
410             sess.span_diagnostic.span_fatal(sp.substitute_dummy(def.span), &s).raise();
411         }
412     };
413
414     let mut valid = true;
415
416     // Extract the arguments:
417     let lhses = match argument_map[&lhs_nm] {
418         MatchedSeq(ref s) => s
419             .iter()
420             .map(|m| {
421                 if let MatchedNonterminal(ref nt) = *m {
422                     if let NtTT(ref tt) = **nt {
423                         let tt = mbe::quoted::parse(tt.clone().into(), true, sess).pop().unwrap();
424                         valid &= check_lhs_nt_follows(sess, features, &def.attrs, &tt);
425                         return tt;
426                     }
427                 }
428                 sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs")
429             })
430             .collect::<Vec<mbe::TokenTree>>(),
431         _ => sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs"),
432     };
433
434     let rhses = match argument_map[&rhs_nm] {
435         MatchedSeq(ref s) => s
436             .iter()
437             .map(|m| {
438                 if let MatchedNonterminal(ref nt) = *m {
439                     if let NtTT(ref tt) = **nt {
440                         return mbe::quoted::parse(tt.clone().into(), false, sess).pop().unwrap();
441                     }
442                 }
443                 sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs")
444             })
445             .collect::<Vec<mbe::TokenTree>>(),
446         _ => sess.span_diagnostic.span_bug(def.span, "wrong-structured rhs"),
447     };
448
449     for rhs in &rhses {
450         valid &= check_rhs(sess, rhs);
451     }
452
453     // don't abort iteration early, so that errors for multiple lhses can be reported
454     for lhs in &lhses {
455         valid &= check_lhs_no_empty_seq(sess, slice::from_ref(lhs));
456     }
457
458     // We use CRATE_NODE_ID instead of `def.id` otherwise we may emit buffered lints for a node id
459     // that is not lint-checked and trigger the "failed to process buffered lint here" bug.
460     valid &= macro_check::check_meta_variables(sess, ast::CRATE_NODE_ID, def.span, &lhses, &rhses);
461
462     let (transparency, transparency_error) = attr::find_transparency(&def.attrs, is_legacy);
463     match transparency_error {
464         Some(TransparencyError::UnknownTransparency(value, span)) => {
465             diag.span_err(span, &format!("unknown macro transparency: `{}`", value))
466         }
467         Some(TransparencyError::MultipleTransparencyAttrs(old_span, new_span)) => {
468             diag.span_err(vec![old_span, new_span], "multiple macro transparency attributes")
469         }
470         None => {}
471     }
472
473     let expander: Box<_> = Box::new(MacroRulesMacroExpander {
474         name: def.ident,
475         span: def.span,
476         transparency,
477         lhses,
478         rhses,
479         valid,
480     });
481
482     SyntaxExtension::new(
483         sess,
484         SyntaxExtensionKind::LegacyBang(expander),
485         def.span,
486         Vec::new(),
487         edition,
488         def.ident.name,
489         &def.attrs,
490     )
491 }
492
493 fn check_lhs_nt_follows(
494     sess: &ParseSess,
495     features: &Features,
496     attrs: &[ast::Attribute],
497     lhs: &mbe::TokenTree,
498 ) -> bool {
499     // lhs is going to be like TokenTree::Delimited(...), where the
500     // entire lhs is those tts. Or, it can be a "bare sequence", not wrapped in parens.
501     if let mbe::TokenTree::Delimited(_, ref tts) = *lhs {
502         check_matcher(sess, features, attrs, &tts.tts)
503     } else {
504         let msg = "invalid macro matcher; matchers must be contained in balanced delimiters";
505         sess.span_diagnostic.span_err(lhs.span(), msg);
506         false
507     }
508     // we don't abort on errors on rejection, the driver will do that for us
509     // after parsing/expansion. we can report every error in every macro this way.
510 }
511
512 /// Checks that the lhs contains no repetition which could match an empty token
513 /// tree, because then the matcher would hang indefinitely.
514 fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[mbe::TokenTree]) -> bool {
515     use mbe::TokenTree;
516     for tt in tts {
517         match *tt {
518             TokenTree::Token(..) | TokenTree::MetaVar(..) | TokenTree::MetaVarDecl(..) => (),
519             TokenTree::Delimited(_, ref del) => {
520                 if !check_lhs_no_empty_seq(sess, &del.tts) {
521                     return false;
522                 }
523             }
524             TokenTree::Sequence(span, ref seq) => {
525                 if seq.separator.is_none()
526                     && seq.tts.iter().all(|seq_tt| match *seq_tt {
527                         TokenTree::MetaVarDecl(_, _, id) => id.name == sym::vis,
528                         TokenTree::Sequence(_, ref sub_seq) => {
529                             sub_seq.kleene.op == mbe::KleeneOp::ZeroOrMore
530                                 || sub_seq.kleene.op == mbe::KleeneOp::ZeroOrOne
531                         }
532                         _ => false,
533                     })
534                 {
535                     let sp = span.entire();
536                     sess.span_diagnostic.span_err(sp, "repetition matches empty token tree");
537                     return false;
538                 }
539                 if !check_lhs_no_empty_seq(sess, &seq.tts) {
540                     return false;
541                 }
542             }
543         }
544     }
545
546     true
547 }
548
549 fn check_rhs(sess: &ParseSess, rhs: &mbe::TokenTree) -> bool {
550     match *rhs {
551         mbe::TokenTree::Delimited(..) => return true,
552         _ => sess.span_diagnostic.span_err(rhs.span(), "macro rhs must be delimited"),
553     }
554     false
555 }
556
557 fn check_matcher(
558     sess: &ParseSess,
559     features: &Features,
560     attrs: &[ast::Attribute],
561     matcher: &[mbe::TokenTree],
562 ) -> bool {
563     let first_sets = FirstSets::new(matcher);
564     let empty_suffix = TokenSet::empty();
565     let err = sess.span_diagnostic.err_count();
566     check_matcher_core(sess, features, attrs, &first_sets, matcher, &empty_suffix);
567     err == sess.span_diagnostic.err_count()
568 }
569
570 // `The FirstSets` for a matcher is a mapping from subsequences in the
571 // matcher to the FIRST set for that subsequence.
572 //
573 // This mapping is partially precomputed via a backwards scan over the
574 // token trees of the matcher, which provides a mapping from each
575 // repetition sequence to its *first* set.
576 //
577 // (Hypothetically, sequences should be uniquely identifiable via their
578 // spans, though perhaps that is false, e.g., for macro-generated macros
579 // that do not try to inject artificial span information. My plan is
580 // to try to catch such cases ahead of time and not include them in
581 // the precomputed mapping.)
582 struct FirstSets {
583     // this maps each TokenTree::Sequence `$(tt ...) SEP OP` that is uniquely identified by its
584     // span in the original matcher to the First set for the inner sequence `tt ...`.
585     //
586     // If two sequences have the same span in a matcher, then map that
587     // span to None (invalidating the mapping here and forcing the code to
588     // use a slow path).
589     first: FxHashMap<Span, Option<TokenSet>>,
590 }
591
592 impl FirstSets {
593     fn new(tts: &[mbe::TokenTree]) -> FirstSets {
594         use mbe::TokenTree;
595
596         let mut sets = FirstSets { first: FxHashMap::default() };
597         build_recur(&mut sets, tts);
598         return sets;
599
600         // walks backward over `tts`, returning the FIRST for `tts`
601         // and updating `sets` at the same time for all sequence
602         // substructure we find within `tts`.
603         fn build_recur(sets: &mut FirstSets, tts: &[TokenTree]) -> TokenSet {
604             let mut first = TokenSet::empty();
605             for tt in tts.iter().rev() {
606                 match *tt {
607                     TokenTree::Token(..) | TokenTree::MetaVar(..) | TokenTree::MetaVarDecl(..) => {
608                         first.replace_with(tt.clone());
609                     }
610                     TokenTree::Delimited(span, ref delimited) => {
611                         build_recur(sets, &delimited.tts[..]);
612                         first.replace_with(delimited.open_tt(span));
613                     }
614                     TokenTree::Sequence(sp, ref seq_rep) => {
615                         let subfirst = build_recur(sets, &seq_rep.tts[..]);
616
617                         match sets.first.entry(sp.entire()) {
618                             Entry::Vacant(vac) => {
619                                 vac.insert(Some(subfirst.clone()));
620                             }
621                             Entry::Occupied(mut occ) => {
622                                 // if there is already an entry, then a span must have collided.
623                                 // This should not happen with typical macro_rules macros,
624                                 // but syntax extensions need not maintain distinct spans,
625                                 // so distinct syntax trees can be assigned the same span.
626                                 // In such a case, the map cannot be trusted; so mark this
627                                 // entry as unusable.
628                                 occ.insert(None);
629                             }
630                         }
631
632                         // If the sequence contents can be empty, then the first
633                         // token could be the separator token itself.
634
635                         if let (Some(sep), true) = (&seq_rep.separator, subfirst.maybe_empty) {
636                             first.add_one_maybe(TokenTree::Token(sep.clone()));
637                         }
638
639                         // Reverse scan: Sequence comes before `first`.
640                         if subfirst.maybe_empty
641                             || seq_rep.kleene.op == mbe::KleeneOp::ZeroOrMore
642                             || seq_rep.kleene.op == mbe::KleeneOp::ZeroOrOne
643                         {
644                             // If sequence is potentially empty, then
645                             // union them (preserving first emptiness).
646                             first.add_all(&TokenSet { maybe_empty: true, ..subfirst });
647                         } else {
648                             // Otherwise, sequence guaranteed
649                             // non-empty; replace first.
650                             first = subfirst;
651                         }
652                     }
653                 }
654             }
655
656             first
657         }
658     }
659
660     // walks forward over `tts` until all potential FIRST tokens are
661     // identified.
662     fn first(&self, tts: &[mbe::TokenTree]) -> TokenSet {
663         use mbe::TokenTree;
664
665         let mut first = TokenSet::empty();
666         for tt in tts.iter() {
667             assert!(first.maybe_empty);
668             match *tt {
669                 TokenTree::Token(..) | TokenTree::MetaVar(..) | TokenTree::MetaVarDecl(..) => {
670                     first.add_one(tt.clone());
671                     return first;
672                 }
673                 TokenTree::Delimited(span, ref delimited) => {
674                     first.add_one(delimited.open_tt(span));
675                     return first;
676                 }
677                 TokenTree::Sequence(sp, ref seq_rep) => {
678                     let subfirst_owned;
679                     let subfirst = match self.first.get(&sp.entire()) {
680                         Some(&Some(ref subfirst)) => subfirst,
681                         Some(&None) => {
682                             subfirst_owned = self.first(&seq_rep.tts[..]);
683                             &subfirst_owned
684                         }
685                         None => {
686                             panic!("We missed a sequence during FirstSets construction");
687                         }
688                     };
689
690                     // If the sequence contents can be empty, then the first
691                     // token could be the separator token itself.
692                     if let (Some(sep), true) = (&seq_rep.separator, subfirst.maybe_empty) {
693                         first.add_one_maybe(TokenTree::Token(sep.clone()));
694                     }
695
696                     assert!(first.maybe_empty);
697                     first.add_all(subfirst);
698                     if subfirst.maybe_empty
699                         || seq_rep.kleene.op == mbe::KleeneOp::ZeroOrMore
700                         || seq_rep.kleene.op == mbe::KleeneOp::ZeroOrOne
701                     {
702                         // Continue scanning for more first
703                         // tokens, but also make sure we
704                         // restore empty-tracking state.
705                         first.maybe_empty = true;
706                         continue;
707                     } else {
708                         return first;
709                     }
710                 }
711             }
712         }
713
714         // we only exit the loop if `tts` was empty or if every
715         // element of `tts` matches the empty sequence.
716         assert!(first.maybe_empty);
717         first
718     }
719 }
720
721 // A set of `mbe::TokenTree`s, which may include `TokenTree::Match`s
722 // (for macro-by-example syntactic variables). It also carries the
723 // `maybe_empty` flag; that is true if and only if the matcher can
724 // match an empty token sequence.
725 //
726 // The First set is computed on submatchers like `$($a:expr b),* $(c)* d`,
727 // which has corresponding FIRST = {$a:expr, c, d}.
728 // Likewise, `$($a:expr b),* $(c)+ d` has FIRST = {$a:expr, c}.
729 //
730 // (Notably, we must allow for *-op to occur zero times.)
731 #[derive(Clone, Debug)]
732 struct TokenSet {
733     tokens: Vec<mbe::TokenTree>,
734     maybe_empty: bool,
735 }
736
737 impl TokenSet {
738     // Returns a set for the empty sequence.
739     fn empty() -> Self {
740         TokenSet { tokens: Vec::new(), maybe_empty: true }
741     }
742
743     // Returns the set `{ tok }` for the single-token (and thus
744     // non-empty) sequence [tok].
745     fn singleton(tok: mbe::TokenTree) -> Self {
746         TokenSet { tokens: vec![tok], maybe_empty: false }
747     }
748
749     // Changes self to be the set `{ tok }`.
750     // Since `tok` is always present, marks self as non-empty.
751     fn replace_with(&mut self, tok: mbe::TokenTree) {
752         self.tokens.clear();
753         self.tokens.push(tok);
754         self.maybe_empty = false;
755     }
756
757     // Changes self to be the empty set `{}`; meant for use when
758     // the particular token does not matter, but we want to
759     // record that it occurs.
760     fn replace_with_irrelevant(&mut self) {
761         self.tokens.clear();
762         self.maybe_empty = false;
763     }
764
765     // Adds `tok` to the set for `self`, marking sequence as non-empy.
766     fn add_one(&mut self, tok: mbe::TokenTree) {
767         if !self.tokens.contains(&tok) {
768             self.tokens.push(tok);
769         }
770         self.maybe_empty = false;
771     }
772
773     // Adds `tok` to the set for `self`. (Leaves `maybe_empty` flag alone.)
774     fn add_one_maybe(&mut self, tok: mbe::TokenTree) {
775         if !self.tokens.contains(&tok) {
776             self.tokens.push(tok);
777         }
778     }
779
780     // Adds all elements of `other` to this.
781     //
782     // (Since this is a set, we filter out duplicates.)
783     //
784     // If `other` is potentially empty, then preserves the previous
785     // setting of the empty flag of `self`. If `other` is guaranteed
786     // non-empty, then `self` is marked non-empty.
787     fn add_all(&mut self, other: &Self) {
788         for tok in &other.tokens {
789             if !self.tokens.contains(tok) {
790                 self.tokens.push(tok.clone());
791             }
792         }
793         if !other.maybe_empty {
794             self.maybe_empty = false;
795         }
796     }
797 }
798
799 // Checks that `matcher` is internally consistent and that it
800 // can legally be followed by a token `N`, for all `N` in `follow`.
801 // (If `follow` is empty, then it imposes no constraint on
802 // the `matcher`.)
803 //
804 // Returns the set of NT tokens that could possibly come last in
805 // `matcher`. (If `matcher` matches the empty sequence, then
806 // `maybe_empty` will be set to true.)
807 //
808 // Requires that `first_sets` is pre-computed for `matcher`;
809 // see `FirstSets::new`.
810 fn check_matcher_core(
811     sess: &ParseSess,
812     features: &Features,
813     attrs: &[ast::Attribute],
814     first_sets: &FirstSets,
815     matcher: &[mbe::TokenTree],
816     follow: &TokenSet,
817 ) -> TokenSet {
818     use mbe::TokenTree;
819
820     let mut last = TokenSet::empty();
821
822     // 2. For each token and suffix  [T, SUFFIX] in M:
823     // ensure that T can be followed by SUFFIX, and if SUFFIX may be empty,
824     // then ensure T can also be followed by any element of FOLLOW.
825     'each_token: for i in 0..matcher.len() {
826         let token = &matcher[i];
827         let suffix = &matcher[i + 1..];
828
829         let build_suffix_first = || {
830             let mut s = first_sets.first(suffix);
831             if s.maybe_empty {
832                 s.add_all(follow);
833             }
834             s
835         };
836
837         // (we build `suffix_first` on demand below; you can tell
838         // which cases are supposed to fall through by looking for the
839         // initialization of this variable.)
840         let suffix_first;
841
842         // First, update `last` so that it corresponds to the set
843         // of NT tokens that might end the sequence `... token`.
844         match *token {
845             TokenTree::Token(..) | TokenTree::MetaVar(..) | TokenTree::MetaVarDecl(..) => {
846                 let can_be_followed_by_any;
847                 if let Err(bad_frag) = has_legal_fragment_specifier(sess, features, attrs, token) {
848                     let msg = format!("invalid fragment specifier `{}`", bad_frag);
849                     sess.span_diagnostic
850                         .struct_span_err(token.span(), &msg)
851                         .help(VALID_FRAGMENT_NAMES_MSG)
852                         .emit();
853                     // (This eliminates false positives and duplicates
854                     // from error messages.)
855                     can_be_followed_by_any = true;
856                 } else {
857                     can_be_followed_by_any = token_can_be_followed_by_any(token);
858                 }
859
860                 if can_be_followed_by_any {
861                     // don't need to track tokens that work with any,
862                     last.replace_with_irrelevant();
863                     // ... and don't need to check tokens that can be
864                     // followed by anything against SUFFIX.
865                     continue 'each_token;
866                 } else {
867                     last.replace_with(token.clone());
868                     suffix_first = build_suffix_first();
869                 }
870             }
871             TokenTree::Delimited(span, ref d) => {
872                 let my_suffix = TokenSet::singleton(d.close_tt(span));
873                 check_matcher_core(sess, features, attrs, first_sets, &d.tts, &my_suffix);
874                 // don't track non NT tokens
875                 last.replace_with_irrelevant();
876
877                 // also, we don't need to check delimited sequences
878                 // against SUFFIX
879                 continue 'each_token;
880             }
881             TokenTree::Sequence(_, ref seq_rep) => {
882                 suffix_first = build_suffix_first();
883                 // The trick here: when we check the interior, we want
884                 // to include the separator (if any) as a potential
885                 // (but not guaranteed) element of FOLLOW. So in that
886                 // case, we make a temp copy of suffix and stuff
887                 // delimiter in there.
888                 //
889                 // FIXME: Should I first scan suffix_first to see if
890                 // delimiter is already in it before I go through the
891                 // work of cloning it? But then again, this way I may
892                 // get a "tighter" span?
893                 let mut new;
894                 let my_suffix = if let Some(sep) = &seq_rep.separator {
895                     new = suffix_first.clone();
896                     new.add_one_maybe(TokenTree::Token(sep.clone()));
897                     &new
898                 } else {
899                     &suffix_first
900                 };
901
902                 // At this point, `suffix_first` is built, and
903                 // `my_suffix` is some TokenSet that we can use
904                 // for checking the interior of `seq_rep`.
905                 let next =
906                     check_matcher_core(sess, features, attrs, first_sets, &seq_rep.tts, my_suffix);
907                 if next.maybe_empty {
908                     last.add_all(&next);
909                 } else {
910                     last = next;
911                 }
912
913                 // the recursive call to check_matcher_core already ran the 'each_last
914                 // check below, so we can just keep going forward here.
915                 continue 'each_token;
916             }
917         }
918
919         // (`suffix_first` guaranteed initialized once reaching here.)
920
921         // Now `last` holds the complete set of NT tokens that could
922         // end the sequence before SUFFIX. Check that every one works with `suffix`.
923         'each_last: for token in &last.tokens {
924             if let TokenTree::MetaVarDecl(_, name, frag_spec) = *token {
925                 for next_token in &suffix_first.tokens {
926                     match is_in_follow(next_token, frag_spec.name) {
927                         IsInFollow::Invalid(msg, help) => {
928                             sess.span_diagnostic
929                                 .struct_span_err(next_token.span(), &msg)
930                                 .help(help)
931                                 .emit();
932                             // don't bother reporting every source of
933                             // conflict for a particular element of `last`.
934                             continue 'each_last;
935                         }
936                         IsInFollow::Yes => {}
937                         IsInFollow::No(possible) => {
938                             let may_be = if last.tokens.len() == 1 && suffix_first.tokens.len() == 1
939                             {
940                                 "is"
941                             } else {
942                                 "may be"
943                             };
944
945                             let sp = next_token.span();
946                             let mut err = sess.span_diagnostic.struct_span_err(
947                                 sp,
948                                 &format!(
949                                     "`${name}:{frag}` {may_be} followed by `{next}`, which \
950                                      is not allowed for `{frag}` fragments",
951                                     name = name,
952                                     frag = frag_spec,
953                                     next = quoted_tt_to_string(next_token),
954                                     may_be = may_be
955                                 ),
956                             );
957                             err.span_label(
958                                 sp,
959                                 format!("not allowed after `{}` fragments", frag_spec),
960                             );
961                             let msg = "allowed there are: ";
962                             match possible {
963                                 &[] => {}
964                                 &[t] => {
965                                     err.note(&format!(
966                                         "only {} is allowed after `{}` fragments",
967                                         t, frag_spec,
968                                     ));
969                                 }
970                                 ts => {
971                                     err.note(&format!(
972                                         "{}{} or {}",
973                                         msg,
974                                         ts[..ts.len() - 1]
975                                             .iter()
976                                             .map(|s| *s)
977                                             .collect::<Vec<_>>()
978                                             .join(", "),
979                                         ts[ts.len() - 1],
980                                     ));
981                                 }
982                             }
983                             err.emit();
984                         }
985                     }
986                 }
987             }
988         }
989     }
990     last
991 }
992
993 fn token_can_be_followed_by_any(tok: &mbe::TokenTree) -> bool {
994     if let mbe::TokenTree::MetaVarDecl(_, _, frag_spec) = *tok {
995         frag_can_be_followed_by_any(frag_spec.name)
996     } else {
997         // (Non NT's can always be followed by anthing in matchers.)
998         true
999     }
1000 }
1001
1002 /// Returns `true` if a fragment of type `frag` can be followed by any sort of
1003 /// token. We use this (among other things) as a useful approximation
1004 /// for when `frag` can be followed by a repetition like `$(...)*` or
1005 /// `$(...)+`. In general, these can be a bit tricky to reason about,
1006 /// so we adopt a conservative position that says that any fragment
1007 /// specifier which consumes at most one token tree can be followed by
1008 /// a fragment specifier (indeed, these fragments can be followed by
1009 /// ANYTHING without fear of future compatibility hazards).
1010 fn frag_can_be_followed_by_any(frag: Symbol) -> bool {
1011     match frag {
1012         sym::item     | // always terminated by `}` or `;`
1013         sym::block    | // exactly one token tree
1014         sym::ident    | // exactly one token tree
1015         sym::literal  | // exactly one token tree
1016         sym::meta     | // exactly one token tree
1017         sym::lifetime | // exactly one token tree
1018         sym::tt =>   // exactly one token tree
1019             true,
1020
1021         _ =>
1022             false,
1023     }
1024 }
1025
1026 enum IsInFollow {
1027     Yes,
1028     No(&'static [&'static str]),
1029     Invalid(String, &'static str),
1030 }
1031
1032 /// Returns `true` if `frag` can legally be followed by the token `tok`. For
1033 /// fragments that can consume an unbounded number of tokens, `tok`
1034 /// must be within a well-defined follow set. This is intended to
1035 /// guarantee future compatibility: for example, without this rule, if
1036 /// we expanded `expr` to include a new binary operator, we might
1037 /// break macros that were relying on that binary operator as a
1038 /// separator.
1039 // when changing this do not forget to update doc/book/macros.md!
1040 fn is_in_follow(tok: &mbe::TokenTree, frag: Symbol) -> IsInFollow {
1041     use mbe::TokenTree;
1042
1043     if let TokenTree::Token(Token { kind: token::CloseDelim(_), .. }) = *tok {
1044         // closing a token tree can never be matched by any fragment;
1045         // iow, we always require that `(` and `)` match, etc.
1046         IsInFollow::Yes
1047     } else {
1048         match frag {
1049             sym::item => {
1050                 // since items *must* be followed by either a `;` or a `}`, we can
1051                 // accept anything after them
1052                 IsInFollow::Yes
1053             }
1054             sym::block => {
1055                 // anything can follow block, the braces provide an easy boundary to
1056                 // maintain
1057                 IsInFollow::Yes
1058             }
1059             sym::stmt | sym::expr => {
1060                 const TOKENS: &[&str] = &["`=>`", "`,`", "`;`"];
1061                 match tok {
1062                     TokenTree::Token(token) => match token.kind {
1063                         FatArrow | Comma | Semi => IsInFollow::Yes,
1064                         _ => IsInFollow::No(TOKENS),
1065                     },
1066                     _ => IsInFollow::No(TOKENS),
1067                 }
1068             }
1069             sym::pat => {
1070                 const TOKENS: &[&str] = &["`=>`", "`,`", "`=`", "`|`", "`if`", "`in`"];
1071                 match tok {
1072                     TokenTree::Token(token) => match token.kind {
1073                         FatArrow | Comma | Eq | BinOp(token::Or) => IsInFollow::Yes,
1074                         Ident(name, false) if name == kw::If || name == kw::In => IsInFollow::Yes,
1075                         _ => IsInFollow::No(TOKENS),
1076                     },
1077                     _ => IsInFollow::No(TOKENS),
1078                 }
1079             }
1080             sym::path | sym::ty => {
1081                 const TOKENS: &[&str] = &[
1082                     "`{`", "`[`", "`=>`", "`,`", "`>`", "`=`", "`:`", "`;`", "`|`", "`as`",
1083                     "`where`",
1084                 ];
1085                 match tok {
1086                     TokenTree::Token(token) => match token.kind {
1087                         OpenDelim(token::DelimToken::Brace)
1088                         | OpenDelim(token::DelimToken::Bracket)
1089                         | Comma
1090                         | FatArrow
1091                         | Colon
1092                         | Eq
1093                         | Gt
1094                         | BinOp(token::Shr)
1095                         | Semi
1096                         | BinOp(token::Or) => IsInFollow::Yes,
1097                         Ident(name, false) if name == kw::As || name == kw::Where => {
1098                             IsInFollow::Yes
1099                         }
1100                         _ => IsInFollow::No(TOKENS),
1101                     },
1102                     TokenTree::MetaVarDecl(_, _, frag) if frag.name == sym::block => {
1103                         IsInFollow::Yes
1104                     }
1105                     _ => IsInFollow::No(TOKENS),
1106                 }
1107             }
1108             sym::ident | sym::lifetime => {
1109                 // being a single token, idents and lifetimes are harmless
1110                 IsInFollow::Yes
1111             }
1112             sym::literal => {
1113                 // literals may be of a single token, or two tokens (negative numbers)
1114                 IsInFollow::Yes
1115             }
1116             sym::meta | sym::tt => {
1117                 // being either a single token or a delimited sequence, tt is
1118                 // harmless
1119                 IsInFollow::Yes
1120             }
1121             sym::vis => {
1122                 // Explicitly disallow `priv`, on the off chance it comes back.
1123                 const TOKENS: &[&str] = &["`,`", "an ident", "a type"];
1124                 match tok {
1125                     TokenTree::Token(token) => match token.kind {
1126                         Comma => IsInFollow::Yes,
1127                         Ident(name, is_raw) if is_raw || name != kw::Priv => IsInFollow::Yes,
1128                         _ => {
1129                             if token.can_begin_type() {
1130                                 IsInFollow::Yes
1131                             } else {
1132                                 IsInFollow::No(TOKENS)
1133                             }
1134                         }
1135                     },
1136                     TokenTree::MetaVarDecl(_, _, frag)
1137                         if frag.name == sym::ident
1138                             || frag.name == sym::ty
1139                             || frag.name == sym::path =>
1140                     {
1141                         IsInFollow::Yes
1142                     }
1143                     _ => IsInFollow::No(TOKENS),
1144                 }
1145             }
1146             kw::Invalid => IsInFollow::Yes,
1147             _ => IsInFollow::Invalid(
1148                 format!("invalid fragment specifier `{}`", frag),
1149                 VALID_FRAGMENT_NAMES_MSG,
1150             ),
1151         }
1152     }
1153 }
1154
1155 fn has_legal_fragment_specifier(
1156     sess: &ParseSess,
1157     features: &Features,
1158     attrs: &[ast::Attribute],
1159     tok: &mbe::TokenTree,
1160 ) -> Result<(), String> {
1161     debug!("has_legal_fragment_specifier({:?})", tok);
1162     if let mbe::TokenTree::MetaVarDecl(_, _, ref frag_spec) = *tok {
1163         let frag_span = tok.span();
1164         if !is_legal_fragment_specifier(sess, features, attrs, frag_spec.name, frag_span) {
1165             return Err(frag_spec.to_string());
1166         }
1167     }
1168     Ok(())
1169 }
1170
1171 fn is_legal_fragment_specifier(
1172     _sess: &ParseSess,
1173     _features: &Features,
1174     _attrs: &[ast::Attribute],
1175     frag_name: Symbol,
1176     _frag_span: Span,
1177 ) -> bool {
1178     /*
1179      * If new fragment specifiers are invented in nightly, `_sess`,
1180      * `_features`, `_attrs`, and `_frag_span` will be useful here
1181      * for checking against feature gates. See past versions of
1182      * this function.
1183      */
1184     match frag_name {
1185         sym::item
1186         | sym::block
1187         | sym::stmt
1188         | sym::expr
1189         | sym::pat
1190         | sym::lifetime
1191         | sym::path
1192         | sym::ty
1193         | sym::ident
1194         | sym::meta
1195         | sym::tt
1196         | sym::vis
1197         | sym::literal
1198         | kw::Invalid => true,
1199         _ => false,
1200     }
1201 }
1202
1203 fn quoted_tt_to_string(tt: &mbe::TokenTree) -> String {
1204     match *tt {
1205         mbe::TokenTree::Token(ref token) => pprust::token_to_string(&token),
1206         mbe::TokenTree::MetaVar(_, name) => format!("${}", name),
1207         mbe::TokenTree::MetaVarDecl(_, name, kind) => format!("${}:{}", name, kind),
1208         _ => panic!(
1209             "unexpected mbe::TokenTree::{{Sequence or Delimited}} \
1210              in follow set checker"
1211         ),
1212     }
1213 }
1214
1215 fn base_parser_from_cx<'cx>(
1216     current_expansion: &'cx ExpansionData,
1217     sess: &'cx ParseSess,
1218     tts: TokenStream,
1219 ) -> Parser<'cx> {
1220     let directory = Directory {
1221         path: current_expansion.module.directory.clone(),
1222         ownership: current_expansion.directory_ownership,
1223     };
1224     Parser::new(sess, tts, Some(directory), true, true, rustc_parse::MACRO_ARGUMENTS)
1225 }
1226
1227 /// Generates an appropriate parsing failure message. For EOF, this is "unexpected end...". For
1228 /// other tokens, this is "unexpected token...".
1229 fn parse_failure_msg(tok: &Token) -> String {
1230     match tok.kind {
1231         token::Eof => "unexpected end of macro invocation".to_string(),
1232         _ => format!("no rules expected the token `{}`", pprust::token_to_string(tok),),
1233     }
1234 }