Skip to content

Commit 9f265a6

Browse files
committed
mbe: Factor out a helper to parse and only keep spans on success
`try_match_macro` does a careful dance of saving the parser's spans, restoring them on failure, and merging them on success. Wrap this in a function, so we can easily reuse it.
1 parent e3fccdd commit 9f265a6

File tree

2 files changed

+33
-21
lines changed

2 files changed

+33
-21
lines changed

compiler/rustc_expand/src/mbe/macro_parser.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
use std::borrow::Cow;
7474
use std::collections::hash_map::Entry::{Occupied, Vacant};
7575
use std::fmt::Display;
76+
use std::mem;
7677
use std::rc::Rc;
7778

7879
pub(crate) use NamedMatch::*;
@@ -689,6 +690,36 @@ impl TtParser {
689690
}
690691
}
691692

693+
/// Match the token stream from `parser` against `matcher`; only keep parsed spans on success.
694+
pub(super) fn parse_tt_preserve_spans<'matcher, T: Tracker<'matcher>>(
695+
&mut self,
696+
parser: &mut Cow<'_, Parser<'_>>,
697+
matcher: &'matcher [MatcherLoc],
698+
track: &mut T,
699+
) -> NamedParseResult<T::Failure> {
700+
// Take a snapshot of the state of pre-expansion gating at this point.
701+
// This is used so that if a matcher is not `Success(..)`ful,
702+
// then the spans which became gated when parsing the unsuccessful matcher
703+
// are not recorded. On the first `Success(..)`ful matcher, the spans are merged.
704+
let mut gated_spans_snapshot = mem::take(&mut *parser.psess.gated_spans.spans.borrow_mut());
705+
let result = self.parse_tt(parser, matcher, track);
706+
track.after_arm(&result);
707+
match &result {
708+
Success(_) => {
709+
// The matcher was `Success(..)`ful.
710+
// Merge the gated spans from parsing the matcher with the preexisting ones.
711+
parser.psess.gated_spans.merge(gated_spans_snapshot);
712+
}
713+
Failure(_) => {
714+
// The matcher failed.
715+
// Restore to the state before snapshotting and maybe try again.
716+
mem::swap(&mut gated_spans_snapshot, &mut parser.psess.gated_spans.spans.borrow_mut());
717+
}
718+
_ => {}
719+
}
720+
result
721+
}
722+
692723
fn ambiguity_error<F>(
693724
&self,
694725
matcher: &[MatcherLoc],

compiler/rustc_expand/src/mbe/macro_rules.rs

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::borrow::Cow;
22
use std::collections::hash_map::Entry;
33
use std::sync::Arc;
4-
use std::{mem, slice};
4+
use std::slice;
55

66
use ast::token::IdentIsRaw;
77
use rustc_ast::token::NtPatKind::*;
@@ -318,24 +318,9 @@ pub(super) fn try_match_macro<'matcher, T: Tracker<'matcher>>(
318318
let mut tt_parser = TtParser::new(name);
319319
for (i, rule) in rules.iter().enumerate() {
320320
let _tracing_span = trace_span!("Matching arm", %i);
321-
322-
// Take a snapshot of the state of pre-expansion gating at this point.
323-
// This is used so that if a matcher is not `Success(..)`ful,
324-
// then the spans which became gated when parsing the unsuccessful matcher
325-
// are not recorded. On the first `Success(..)`ful matcher, the spans are merged.
326-
let mut gated_spans_snapshot = mem::take(&mut *psess.gated_spans.spans.borrow_mut());
327-
328-
let result = tt_parser.parse_tt(&mut Cow::Borrowed(&parser), &rule.lhs, track);
329-
330-
track.after_arm(&result);
331-
332-
match result {
321+
match tt_parser.parse_tt_preserve_spans(&mut Cow::Borrowed(&parser), &rule.lhs, track) {
333322
Success(named_matches) => {
334323
debug!("Parsed arm successfully");
335-
// The matcher was `Success(..)`ful.
336-
// Merge the gated spans from parsing the matcher with the preexisting ones.
337-
psess.gated_spans.merge(gated_spans_snapshot);
338-
339324
return Ok((i, rule, named_matches));
340325
}
341326
Failure(_) => {
@@ -353,10 +338,6 @@ pub(super) fn try_match_macro<'matcher, T: Tracker<'matcher>>(
353338
return Err(CanRetry::No(guarantee));
354339
}
355340
}
356-
357-
// The matcher was not `Success(..)`ful.
358-
// Restore to the state before snapshotting and maybe try again.
359-
mem::swap(&mut gated_spans_snapshot, &mut psess.gated_spans.spans.borrow_mut());
360341
}
361342

362343
Err(CanRetry::Yes)

0 commit comments

Comments
 (0)