summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_expand/src/mbe/macro_parser.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_expand/src/mbe/macro_parser.rs')
-rw-r--r--compiler/rustc_expand/src/mbe/macro_parser.rs37
1 files changed, 23 insertions, 14 deletions
diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs
index d161868ed..2e199541b 100644
--- a/compiler/rustc_expand/src/mbe/macro_parser.rs
+++ b/compiler/rustc_expand/src/mbe/macro_parser.rs
@@ -305,12 +305,13 @@ enum EofMatcherPositions {
}
/// Represents the possible results of an attempted parse.
-pub(crate) enum ParseResult<T> {
+pub(crate) enum ParseResult<T, F> {
/// Parsed successfully.
Success(T),
/// Arm failed to match. If the second parameter is `token::Eof`, it indicates an unexpected
/// end of macro invocation. Otherwise, it indicates that no rules expected the given token.
- Failure(Token, &'static str),
+ /// The usize is the approximate position of the token in the input token stream.
+ Failure(F),
/// Fatal error (malformed macro?). Abort compilation.
Error(rustc_span::Span, String),
ErrorReported(ErrorGuaranteed),
@@ -319,7 +320,7 @@ pub(crate) enum ParseResult<T> {
/// A `ParseResult` where the `Success` variant contains a mapping of
/// `MacroRulesNormalizedIdent`s to `NamedMatch`es. This represents the mapping
/// of metavars to the token trees they bind to.
-pub(crate) type NamedParseResult = ParseResult<NamedMatches>;
+pub(crate) type NamedParseResult<F> = ParseResult<NamedMatches, F>;
/// Contains a mapping of `MacroRulesNormalizedIdent`s to `NamedMatch`es.
/// This represents the mapping of metavars to the token trees they bind to.
@@ -455,8 +456,9 @@ impl TtParser {
&mut self,
matcher: &'matcher [MatcherLoc],
token: &Token,
+ approx_position: usize,
track: &mut T,
- ) -> Option<NamedParseResult> {
+ ) -> Option<NamedParseResult<T::Failure>> {
// Matcher positions that would be valid if the macro invocation was over now. Only
// modified if `token == Eof`.
let mut eof_mps = EofMatcherPositions::None;
@@ -593,13 +595,14 @@ impl TtParser {
EofMatcherPositions::Multiple => {
Error(token.span, "ambiguity: multiple successful parses".to_string())
}
- EofMatcherPositions::None => Failure(
+ EofMatcherPositions::None => Failure(T::build_failure(
Token::new(
token::Eof,
if token.span.is_dummy() { token.span } else { token.span.shrink_to_hi() },
),
+ approx_position,
"missing tokens in macro arguments",
- ),
+ )),
})
} else {
None
@@ -612,7 +615,7 @@ impl TtParser {
parser: &mut Cow<'_, Parser<'_>>,
matcher: &'matcher [MatcherLoc],
track: &mut T,
- ) -> NamedParseResult {
+ ) -> NamedParseResult<T::Failure> {
// A queue of possible matcher positions. We initialize it with the matcher position in
// which the "dot" is before the first token of the first token tree in `matcher`.
// `parse_tt_inner` then processes all of these possible matcher positions and produces
@@ -627,7 +630,12 @@ impl TtParser {
// Process `cur_mps` until either we have finished the input or we need to get some
// parsing from the black-box parser done.
- let res = self.parse_tt_inner(matcher, &parser.token, track);
+ let res = self.parse_tt_inner(
+ matcher,
+ &parser.token,
+ parser.approx_token_stream_pos(),
+ track,
+ );
if let Some(res) = res {
return res;
}
@@ -640,10 +648,11 @@ impl TtParser {
(0, 0) => {
// There are no possible next positions AND we aren't waiting for the black-box
// parser: syntax error.
- return Failure(
+ return Failure(T::build_failure(
parser.token.clone(),
+ parser.approx_token_stream_pos(),
"no rules expected this token in macro call",
- );
+ ));
}
(_, 0) => {
@@ -702,11 +711,11 @@ impl TtParser {
}
}
- fn ambiguity_error(
+ fn ambiguity_error<F>(
&self,
matcher: &[MatcherLoc],
token_span: rustc_span::Span,
- ) -> NamedParseResult {
+ ) -> NamedParseResult<F> {
let nts = self
.bb_mps
.iter()
@@ -732,11 +741,11 @@ impl TtParser {
)
}
- fn nameize<I: Iterator<Item = NamedMatch>>(
+ fn nameize<I: Iterator<Item = NamedMatch>, F>(
&self,
matcher: &[MatcherLoc],
mut res: I,
- ) -> NamedParseResult {
+ ) -> NamedParseResult<F> {
// Make that each metavar has _exactly one_ binding. If so, insert the binding into the
// `NamedParseResult`. Otherwise, it's an error.
let mut ret_val = FxHashMap::default();