Skip to content

Commit

Permalink
Refactor ensure_complete_parse.
Browse files Browse the repository at this point in the history
  • Loading branch information
jseyfried committed Sep 26, 2016
1 parent 4a8467b commit b90cedd
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 45 deletions.
20 changes: 8 additions & 12 deletions src/libsyntax/ext/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// except according to those terms.

use ast::{Block, Crate, Ident, Mac_, PatKind};
use ast::{MacStmtStyle, StmtKind, ItemKind};
use ast::{Name, MacStmtStyle, StmtKind, ItemKind};
use ast;
use ext::hygiene::Mark;
use ext::placeholders::{placeholder, PlaceholderExpander};
Expand Down Expand Up @@ -299,10 +299,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
};

attr::mark_used(&attr);
let name = intern(&attr.name());
self.cx.bt_push(ExpnInfo {
call_site: attr.span,
callee: NameAndSpan {
format: MacroAttribute(intern(&attr.name())),
format: MacroAttribute(name),
span: Some(attr.span),
allow_internal_unstable: false,
}
Expand All @@ -325,7 +326,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
let item_toks = TokenStream::from_tts(tts_for_item(&item, &self.cx.parse_sess));

let tok_result = mac.expand(self.cx, attr.span, attr_toks, item_toks);
self.parse_expansion(tok_result, kind, attr.span)
self.parse_expansion(tok_result, kind, name, attr.span)
}
_ => unreachable!(),
}
Expand Down Expand Up @@ -424,7 +425,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {

let toks = TokenStream::from_tts(marked_tts);
let tok_result = expandfun.expand(self.cx, span, toks);
Some(self.parse_expansion(tok_result, kind, span))
Some(self.parse_expansion(tok_result, kind, extname, span))
}
};

Expand All @@ -443,7 +444,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
})
}

fn parse_expansion(&mut self, toks: TokenStream, kind: ExpansionKind, span: Span) -> Expansion {
fn parse_expansion(&mut self, toks: TokenStream, kind: ExpansionKind, name: Name, span: Span)
-> Expansion {
let mut parser = self.cx.new_parser_from_tts(&toks.to_tts());
let expansion = match parser.parse_expansion(kind, false) {
Ok(expansion) => expansion,
Expand All @@ -452,13 +454,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
return kind.dummy(span);
}
};
parser.ensure_complete_parse(kind == ExpansionKind::Expr, |parser| {
let msg = format!("macro expansion ignores token `{}` and any following",
parser.this_token_to_string());
parser.diagnostic().struct_span_err(parser.span, &msg)
.span_note(span, "caused by the macro expansion here")
.emit();
});
parser.ensure_complete_parse(name, kind.name(), span);
// FIXME better span info
expansion.fold_with(&mut ChangeSpan { span: span })
}
Expand Down
35 changes: 11 additions & 24 deletions src/libsyntax/ext/tt/macro_rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,32 +39,19 @@ pub struct ParserAnyMacro<'a> {
}

impl<'a> ParserAnyMacro<'a> {
/// Make sure we don't have any tokens left to parse, so we don't
/// silently drop anything. `allow_semi` is so that "optional"
/// semicolons at the end of normal expressions aren't complained
/// about e.g. the semicolon in `macro_rules! kapow { () => {
/// panic!(); } }` doesn't get picked up by .parse_expr(), but it's
/// allowed to be there.
fn ensure_complete_parse(&mut self, allow_semi: bool, context: &str) {
pub fn make(mut self: Box<ParserAnyMacro<'a>>, kind: ExpansionKind) -> Expansion {
let ParserAnyMacro { site_span, macro_ident, ref mut parser } = *self;
parser.ensure_complete_parse(allow_semi, |parser| {
let token_str = parser.this_token_to_string();
let msg = format!("macro expansion ignores token `{}` and any \
following",
token_str);
let span = parser.span;
let mut err = parser.diagnostic().struct_span_err(span, &msg);
let msg = format!("caused by the macro expansion here; the usage \
of `{}!` is likely invalid in {} context",
macro_ident, context);
err.span_note(site_span, &msg)
.emit();
});
}
let expansion = panictry!(parser.parse_expansion(kind, true));

pub fn make(mut self: Box<ParserAnyMacro<'a>>, kind: ExpansionKind) -> Expansion {
let expansion = panictry!(self.parser.parse_expansion(kind, true));
self.ensure_complete_parse(kind == ExpansionKind::Expr, kind.name());
// We allow semicolons at the end of expressions -- e.g. the semicolon in
// `macro_rules! m { () => { panic!(); } }` isn't parsed by `.parse_expr()`,
// but `m!()` is allowed in expression positions (c.f. issue #34706).
if kind == ExpansionKind::Expr && parser.token == token::Semi {
parser.bump();
}

// Make sure we don't have any tokens left to parse so we don't silently drop anything.
parser.ensure_complete_parse(macro_ident.name, kind.name(), site_span);
expansion
}
}
Expand Down
21 changes: 12 additions & 9 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6172,14 +6172,17 @@ impl<'a> Parser<'a> {
}
}

pub fn ensure_complete_parse<F>(&mut self, allow_semi: bool, on_err: F)
where F: FnOnce(&Parser)
{
if allow_semi && self.token == token::Semi {
self.bump();
}
if self.token != token::Eof {
on_err(self);
}
pub fn ensure_complete_parse(&mut self, macro_name: ast::Name, kind_name: &str, span: Span) {
if self.token == token::Eof {
return
}

let msg = format!("macro expansion ignores token `{}` and any following",
self.this_token_to_string());
let mut err = self.diagnostic().struct_span_err(self.span, &msg);
let msg = format!("caused by the macro expansion here; the usage \
of `{}!` is likely invalid in {} context",
macro_name, kind_name);
err.span_note(span, &msg).emit();
}
}

0 comments on commit b90cedd

Please sign in to comment.