Skip to content

Commit 1599461

Browse files
committed
Refactor ext::tt::macro_rules::compile to take a ParseSess instead of an ExtCtxt.
1 parent ee959a8 commit 1599461

File tree

2 files changed

+33
-40
lines changed

2 files changed

+33
-40
lines changed

src/libsyntax/ext/base.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,7 @@ impl<'a> ExtCtxt<'a> {
816816
self.exported_macros.push(def.clone());
817817
}
818818
if def.use_locally {
819-
let ext = macro_rules::compile(self, &def);
819+
let ext = macro_rules::compile(self.parse_sess, &def);
820820
self.resolver.add_macro(self.current_expansion.mark, def.ident, Rc::new(ext));
821821
}
822822
}

src/libsyntax/ext/tt/macro_rules.rs

+32-39
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use ext::placeholders;
1616
use ext::tt::macro_parser::{Success, Error, Failure};
1717
use ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal};
1818
use ext::tt::macro_parser::parse;
19+
use parse::ParseSess;
1920
use parse::lexer::new_tt_reader;
2021
use parse::parser::{Parser, Restrictions};
2122
use parse::token::{self, gensym_ident, NtTT, Token};
@@ -204,7 +205,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
204205
_ => cx.span_bug(sp, "malformed macro rhs"),
205206
};
206207
// rhs has holes ( `$id` and `$(...)` that need filled)
207-
let trncbr = new_tt_reader(&cx.parse_sess().span_diagnostic,
208+
let trncbr = new_tt_reader(&cx.parse_sess.span_diagnostic,
208209
Some(named_matches),
209210
imported_from,
210211
rhs);
@@ -278,9 +279,7 @@ impl IdentMacroExpander for MacroRulesExpander {
278279
// Holy self-referential!
279280

280281
/// Converts a `macro_rules!` invocation into a syntax extension.
281-
pub fn compile<'cx>(cx: &'cx mut ExtCtxt,
282-
def: &ast::MacroDef) -> SyntaxExtension {
283-
282+
pub fn compile(sess: &ParseSess, def: &ast::MacroDef) -> SyntaxExtension {
284283
let lhs_nm = gensym_ident("lhs");
285284
let rhs_nm = gensym_ident("rhs");
286285

@@ -312,19 +311,12 @@ pub fn compile<'cx>(cx: &'cx mut ExtCtxt,
312311
];
313312

314313
// Parse the macro_rules! invocation (`none` is for no interpolations):
315-
let arg_reader = new_tt_reader(&cx.parse_sess().span_diagnostic,
316-
None,
317-
None,
318-
def.body.clone());
319-
320-
let argument_map = match parse(cx.parse_sess(),
321-
cx.cfg(),
322-
arg_reader,
323-
&argument_gram) {
314+
let arg_reader = new_tt_reader(&sess.span_diagnostic, None, None, def.body.clone());
315+
316+
let argument_map = match parse(sess, Vec::new(), arg_reader, &argument_gram) {
324317
Success(m) => m,
325318
Failure(sp, str) | Error(sp, str) => {
326-
panic!(cx.parse_sess().span_diagnostic
327-
.span_fatal(sp.substitute_dummy(def.span), &str[..]));
319+
panic!(sess.span_diagnostic.span_fatal(sp.substitute_dummy(def.span), &str));
328320
}
329321
};
330322

@@ -335,27 +327,27 @@ pub fn compile<'cx>(cx: &'cx mut ExtCtxt,
335327
MatchedSeq(ref s, _) => {
336328
s.iter().map(|m| match **m {
337329
MatchedNonterminal(NtTT(ref tt)) => {
338-
valid &= check_lhs_nt_follows(cx, tt);
330+
valid &= check_lhs_nt_follows(sess, tt);
339331
(**tt).clone()
340332
}
341-
_ => cx.span_bug(def.span, "wrong-structured lhs")
333+
_ => sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs")
342334
}).collect()
343335
}
344-
_ => cx.span_bug(def.span, "wrong-structured lhs")
336+
_ => sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs")
345337
};
346338

347339
let rhses = match **argument_map.get(&rhs_nm).unwrap() {
348340
MatchedSeq(ref s, _) => {
349341
s.iter().map(|m| match **m {
350342
MatchedNonterminal(NtTT(ref tt)) => (**tt).clone(),
351-
_ => cx.span_bug(def.span, "wrong-structured rhs")
343+
_ => sess.span_diagnostic.span_bug(def.span, "wrong-structured rhs")
352344
}).collect()
353345
}
354-
_ => cx.span_bug(def.span, "wrong-structured rhs")
346+
_ => sess.span_diagnostic.span_bug(def.span, "wrong-structured rhs")
355347
};
356348

357349
for rhs in &rhses {
358-
valid &= check_rhs(cx, rhs);
350+
valid &= check_rhs(sess, rhs);
359351
}
360352

361353
let exp: Box<_> = Box::new(MacroRulesMacroExpander {
@@ -369,35 +361,35 @@ pub fn compile<'cx>(cx: &'cx mut ExtCtxt,
369361
NormalTT(exp, Some(def.span), def.allow_internal_unstable)
370362
}
371363

372-
fn check_lhs_nt_follows(cx: &mut ExtCtxt, lhs: &TokenTree) -> bool {
364+
fn check_lhs_nt_follows(sess: &ParseSess, lhs: &TokenTree) -> bool {
373365
// lhs is going to be like TokenTree::Delimited(...), where the
374366
// entire lhs is those tts. Or, it can be a "bare sequence", not wrapped in parens.
375367
match lhs {
376-
&TokenTree::Delimited(_, ref tts) => check_matcher(cx, &tts.tts),
368+
&TokenTree::Delimited(_, ref tts) => check_matcher(sess, &tts.tts),
377369
_ => {
378-
cx.span_err(lhs.get_span(), "invalid macro matcher; matchers must \
379-
be contained in balanced delimiters");
370+
let msg = "invalid macro matcher; matchers must be contained in balanced delimiters";
371+
sess.span_diagnostic.span_err(lhs.get_span(), msg);
380372
false
381373
}
382374
}
383375
// we don't abort on errors on rejection, the driver will do that for us
384376
// after parsing/expansion. we can report every error in every macro this way.
385377
}
386378

387-
fn check_rhs(cx: &mut ExtCtxt, rhs: &TokenTree) -> bool {
379+
fn check_rhs(sess: &ParseSess, rhs: &TokenTree) -> bool {
388380
match *rhs {
389381
TokenTree::Delimited(..) => return true,
390-
_ => cx.span_err(rhs.get_span(), "macro rhs must be delimited")
382+
_ => sess.span_diagnostic.span_err(rhs.get_span(), "macro rhs must be delimited")
391383
}
392384
false
393385
}
394386

395-
fn check_matcher(cx: &mut ExtCtxt, matcher: &[TokenTree]) -> bool {
387+
fn check_matcher(sess: &ParseSess, matcher: &[TokenTree]) -> bool {
396388
let first_sets = FirstSets::new(matcher);
397389
let empty_suffix = TokenSet::empty();
398-
let err = cx.parse_sess.span_diagnostic.err_count();
399-
check_matcher_core(cx, &first_sets, matcher, &empty_suffix);
400-
err == cx.parse_sess.span_diagnostic.err_count()
390+
let err = sess.span_diagnostic.err_count();
391+
check_matcher_core(sess, &first_sets, matcher, &empty_suffix);
392+
err == sess.span_diagnostic.err_count()
401393
}
402394

403395
// The FirstSets for a matcher is a mapping from subsequences in the
@@ -635,7 +627,7 @@ impl TokenSet {
635627
//
636628
// Requires that `first_sets` is pre-computed for `matcher`;
637629
// see `FirstSets::new`.
638-
fn check_matcher_core(cx: &mut ExtCtxt,
630+
fn check_matcher_core(sess: &ParseSess,
639631
first_sets: &FirstSets,
640632
matcher: &[TokenTree],
641633
follow: &TokenSet) -> TokenSet {
@@ -667,7 +659,8 @@ fn check_matcher_core(cx: &mut ExtCtxt,
667659
TokenTree::Token(sp, ref tok) => {
668660
let can_be_followed_by_any;
669661
if let Err(bad_frag) = has_legal_fragment_specifier(tok) {
670-
cx.struct_span_err(sp, &format!("invalid fragment specifier `{}`", bad_frag))
662+
let msg = format!("invalid fragment specifier `{}`", bad_frag);
663+
sess.span_diagnostic.struct_span_err(sp, &msg)
671664
.help("valid fragment specifiers are `ident`, `block`, \
672665
`stmt`, `expr`, `pat`, `ty`, `path`, `meta`, `tt` \
673666
and `item`")
@@ -692,7 +685,7 @@ fn check_matcher_core(cx: &mut ExtCtxt,
692685
}
693686
TokenTree::Delimited(_, ref d) => {
694687
let my_suffix = TokenSet::singleton((d.close_span, Token::CloseDelim(d.delim)));
695-
check_matcher_core(cx, first_sets, &d.tts, &my_suffix);
688+
check_matcher_core(sess, first_sets, &d.tts, &my_suffix);
696689
// don't track non NT tokens
697690
last.replace_with_irrelevant();
698691

@@ -724,7 +717,7 @@ fn check_matcher_core(cx: &mut ExtCtxt,
724717
// At this point, `suffix_first` is built, and
725718
// `my_suffix` is some TokenSet that we can use
726719
// for checking the interior of `seq_rep`.
727-
let next = check_matcher_core(cx, first_sets, &seq_rep.tts, my_suffix);
720+
let next = check_matcher_core(sess, first_sets, &seq_rep.tts, my_suffix);
728721
if next.maybe_empty {
729722
last.add_all(&next);
730723
} else {
@@ -744,9 +737,9 @@ fn check_matcher_core(cx: &mut ExtCtxt,
744737
'each_last: for &(_sp, ref t) in &last.tokens {
745738
if let MatchNt(ref name, ref frag_spec) = *t {
746739
for &(sp, ref next_token) in &suffix_first.tokens {
747-
match is_in_follow(cx, next_token, &frag_spec.name.as_str()) {
740+
match is_in_follow(next_token, &frag_spec.name.as_str()) {
748741
Err((msg, help)) => {
749-
cx.struct_span_err(sp, &msg).help(help).emit();
742+
sess.span_diagnostic.struct_span_err(sp, &msg).help(help).emit();
750743
// don't bother reporting every source of
751744
// conflict for a particular element of `last`.
752745
continue 'each_last;
@@ -761,7 +754,7 @@ fn check_matcher_core(cx: &mut ExtCtxt,
761754
"may be"
762755
};
763756

764-
cx.span_err(
757+
sess.span_diagnostic.span_err(
765758
sp,
766759
&format!("`${name}:{frag}` {may_be} followed by `{next}`, which \
767760
is not allowed for `{frag}` fragments",
@@ -818,7 +811,7 @@ fn frag_can_be_followed_by_any(frag: &str) -> bool {
818811
/// break macros that were relying on that binary operator as a
819812
/// separator.
820813
// when changing this do not forget to update doc/book/macros.md!
821-
fn is_in_follow(_: &ExtCtxt, tok: &Token, frag: &str) -> Result<bool, (String, &'static str)> {
814+
fn is_in_follow(tok: &Token, frag: &str) -> Result<bool, (String, &'static str)> {
822815
if let &CloseDelim(_) = tok {
823816
// closing a token tree can never be matched by any fragment;
824817
// iow, we always require that `(` and `)` match, etc.

0 commit comments

Comments
 (0)