Remove TokResult
.
This commit is contained in:
parent
8b40eaddf1
commit
4a8467b62d
3 changed files with 29 additions and 161 deletions
|
@ -18,8 +18,7 @@ use errors::DiagnosticBuilder;
|
||||||
use ext::expand::{self, Invocation, Expansion};
|
use ext::expand::{self, Invocation, Expansion};
|
||||||
use ext::hygiene::Mark;
|
use ext::hygiene::Mark;
|
||||||
use fold::{self, Folder};
|
use fold::{self, Folder};
|
||||||
use parse;
|
use parse::{self, parser};
|
||||||
use parse::parser::{self, Parser};
|
|
||||||
use parse::token;
|
use parse::token;
|
||||||
use parse::token::{InternedString, str_to_ident};
|
use parse::token::{InternedString, str_to_ident};
|
||||||
use ptr::P;
|
use ptr::P;
|
||||||
|
@ -188,146 +187,6 @@ impl<F> AttrProcMacro for F
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TokResult<'a> {
|
|
||||||
pub parser: Parser<'a>,
|
|
||||||
pub span: Span,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> TokResult<'a> {
|
|
||||||
// There is quite a lot of overlap here with ParserAnyMacro in ext/tt/macro_rules.rs
|
|
||||||
// We could probably share more code.
|
|
||||||
// FIXME(#36641) Unify TokResult and ParserAnyMacro.
|
|
||||||
fn ensure_complete_parse(&mut self, allow_semi: bool) {
|
|
||||||
let macro_span = &self.span;
|
|
||||||
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;
|
|
||||||
parser.diagnostic()
|
|
||||||
.struct_span_err(span, &msg)
|
|
||||||
.span_note(*macro_span, "caused by the macro expansion here")
|
|
||||||
.emit();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> MacResult for TokResult<'a> {
|
|
||||||
fn make_items(mut self: Box<Self>) -> Option<SmallVector<P<ast::Item>>> {
|
|
||||||
if self.parser.sess.span_diagnostic.has_errors() {
|
|
||||||
return Some(SmallVector::zero());
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut items = SmallVector::zero();
|
|
||||||
loop {
|
|
||||||
match self.parser.parse_item() {
|
|
||||||
Ok(Some(item)) => items.push(item),
|
|
||||||
Ok(None) => {
|
|
||||||
self.ensure_complete_parse(false);
|
|
||||||
return Some(items);
|
|
||||||
}
|
|
||||||
Err(mut e) => {
|
|
||||||
e.emit();
|
|
||||||
return Some(SmallVector::zero());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn make_impl_items(mut self: Box<Self>) -> Option<SmallVector<ast::ImplItem>> {
|
|
||||||
let mut items = SmallVector::zero();
|
|
||||||
loop {
|
|
||||||
if self.parser.token == token::Eof {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
match self.parser.parse_impl_item() {
|
|
||||||
Ok(item) => items.push(item),
|
|
||||||
Err(mut e) => {
|
|
||||||
e.emit();
|
|
||||||
return Some(SmallVector::zero());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.ensure_complete_parse(false);
|
|
||||||
Some(items)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn make_trait_items(mut self: Box<Self>) -> Option<SmallVector<ast::TraitItem>> {
|
|
||||||
let mut items = SmallVector::zero();
|
|
||||||
loop {
|
|
||||||
if self.parser.token == token::Eof {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
match self.parser.parse_trait_item() {
|
|
||||||
Ok(item) => items.push(item),
|
|
||||||
Err(mut e) => {
|
|
||||||
e.emit();
|
|
||||||
return Some(SmallVector::zero());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.ensure_complete_parse(false);
|
|
||||||
Some(items)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn make_expr(mut self: Box<Self>) -> Option<P<ast::Expr>> {
|
|
||||||
match self.parser.parse_expr() {
|
|
||||||
Ok(e) => {
|
|
||||||
self.ensure_complete_parse(true);
|
|
||||||
Some(e)
|
|
||||||
}
|
|
||||||
Err(mut e) => {
|
|
||||||
e.emit();
|
|
||||||
Some(DummyResult::raw_expr(self.span))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn make_pat(mut self: Box<Self>) -> Option<P<ast::Pat>> {
|
|
||||||
match self.parser.parse_pat() {
|
|
||||||
Ok(e) => {
|
|
||||||
self.ensure_complete_parse(false);
|
|
||||||
Some(e)
|
|
||||||
}
|
|
||||||
Err(mut e) => {
|
|
||||||
e.emit();
|
|
||||||
Some(P(DummyResult::raw_pat(self.span)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn make_stmts(mut self: Box<Self>) -> Option<SmallVector<ast::Stmt>> {
|
|
||||||
let mut stmts = SmallVector::zero();
|
|
||||||
loop {
|
|
||||||
if self.parser.token == token::Eof {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
match self.parser.parse_full_stmt(false) {
|
|
||||||
Ok(Some(stmt)) => stmts.push(stmt),
|
|
||||||
Ok(None) => { /* continue */ }
|
|
||||||
Err(mut e) => {
|
|
||||||
e.emit();
|
|
||||||
return Some(SmallVector::zero());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.ensure_complete_parse(false);
|
|
||||||
Some(stmts)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn make_ty(mut self: Box<Self>) -> Option<P<ast::Ty>> {
|
|
||||||
match self.parser.parse_ty() {
|
|
||||||
Ok(e) => {
|
|
||||||
self.ensure_complete_parse(false);
|
|
||||||
Some(e)
|
|
||||||
}
|
|
||||||
Err(mut e) => {
|
|
||||||
e.emit();
|
|
||||||
Some(DummyResult::raw_ty(self.span))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents a thing that maps token trees to Macro Results
|
/// Represents a thing that maps token trees to Macro Results
|
||||||
pub trait TTMacroExpander {
|
pub trait TTMacroExpander {
|
||||||
fn expand<'cx>(&self,
|
fn expand<'cx>(&self,
|
||||||
|
|
|
@ -325,14 +325,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
let item_toks = TokenStream::from_tts(tts_for_item(&item, &self.cx.parse_sess));
|
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);
|
let tok_result = mac.expand(self.cx, attr.span, attr_toks, item_toks);
|
||||||
let parser = self.cx.new_parser_from_tts(&tok_result.to_tts());
|
self.parse_expansion(tok_result, kind, attr.span)
|
||||||
let result = Box::new(TokResult { parser: parser, span: attr.span });
|
|
||||||
|
|
||||||
kind.make_from(result).unwrap_or_else(|| {
|
|
||||||
let msg = format!("macro could not be expanded into {} position", kind.name());
|
|
||||||
self.cx.span_err(attr.span, &msg);
|
|
||||||
kind.dummy(attr.span)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
@ -429,14 +422,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let toks = TokenStream::from_tts(marked_tts);
|
||||||
let tok_result = expandfun.expand(self.cx,
|
let tok_result = expandfun.expand(self.cx, span, toks);
|
||||||
span,
|
Some(self.parse_expansion(tok_result, kind, span))
|
||||||
TokenStream::from_tts(marked_tts));
|
|
||||||
let parser = self.cx.new_parser_from_tts(&tok_result.to_tts());
|
|
||||||
let result = Box::new(TokResult { parser: parser, span: span });
|
|
||||||
// FIXME better span info.
|
|
||||||
kind.make_from(result).map(|i| i.fold_with(&mut ChangeSpan { span: span }))
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -454,10 +442,31 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
expn_id: Some(self.cx.backtrace()),
|
expn_id: Some(self.cx.backtrace()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_expansion(&mut self, toks: TokenStream, kind: ExpansionKind, 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,
|
||||||
|
Err(mut err) => {
|
||||||
|
err.emit();
|
||||||
|
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();
|
||||||
|
});
|
||||||
|
// FIXME better span info
|
||||||
|
expansion.fold_with(&mut ChangeSpan { span: span })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Parser<'a> {
|
impl<'a> Parser<'a> {
|
||||||
pub fn parse_expansion(&mut self, kind: ExpansionKind) -> PResult<'a, Expansion> {
|
pub fn parse_expansion(&mut self, kind: ExpansionKind, macro_legacy_warnings: bool)
|
||||||
|
-> PResult<'a, Expansion> {
|
||||||
Ok(match kind {
|
Ok(match kind {
|
||||||
ExpansionKind::Items => {
|
ExpansionKind::Items => {
|
||||||
let mut items = SmallVector::zero();
|
let mut items = SmallVector::zero();
|
||||||
|
@ -483,7 +492,7 @@ impl<'a> Parser<'a> {
|
||||||
ExpansionKind::Stmts => {
|
ExpansionKind::Stmts => {
|
||||||
let mut stmts = SmallVector::zero();
|
let mut stmts = SmallVector::zero();
|
||||||
while self.token != token::Eof {
|
while self.token != token::Eof {
|
||||||
if let Some(stmt) = self.parse_full_stmt(true)? {
|
if let Some(stmt) = self.parse_full_stmt(macro_legacy_warnings)? {
|
||||||
stmts.push(stmt);
|
stmts.push(stmt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ impl<'a> ParserAnyMacro<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn make(mut self: Box<ParserAnyMacro<'a>>, kind: ExpansionKind) -> Expansion {
|
pub fn make(mut self: Box<ParserAnyMacro<'a>>, kind: ExpansionKind) -> Expansion {
|
||||||
let expansion = panictry!(self.parser.parse_expansion(kind));
|
let expansion = panictry!(self.parser.parse_expansion(kind, true));
|
||||||
self.ensure_complete_parse(kind == ExpansionKind::Expr, kind.name());
|
self.ensure_complete_parse(kind == ExpansionKind::Expr, kind.name());
|
||||||
expansion
|
expansion
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue