Skip to content

Commit ae77889

Browse files
author
Jonathan Turner
authored
Rollup merge of rust-lang#36669 - jseyfried:refactor_tok_result, r=nrc
Unify `TokResult` and `ResultAnyMacro` Fixes rust-lang#36641. r? @nrc
2 parents f685380 + df0e4bf commit ae77889

File tree

4 files changed

+103
-280
lines changed

4 files changed

+103
-280
lines changed

src/libsyntax/ext/base.rs

+1-142
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ use errors::DiagnosticBuilder;
1818
use ext::expand::{self, Invocation, Expansion};
1919
use ext::hygiene::Mark;
2020
use fold::{self, Folder};
21-
use parse;
22-
use parse::parser::{self, Parser};
21+
use parse::{self, parser};
2322
use parse::token;
2423
use parse::token::{InternedString, str_to_ident};
2524
use ptr::P;
@@ -188,146 +187,6 @@ impl<F> AttrProcMacro for F
188187
}
189188
}
190189

191-
pub struct TokResult<'a> {
192-
pub parser: Parser<'a>,
193-
pub span: Span,
194-
}
195-
196-
impl<'a> TokResult<'a> {
197-
// There is quite a lot of overlap here with ParserAnyMacro in ext/tt/macro_rules.rs
198-
// We could probably share more code.
199-
// FIXME(#36641) Unify TokResult and ParserAnyMacro.
200-
fn ensure_complete_parse(&mut self, allow_semi: bool) {
201-
let macro_span = &self.span;
202-
self.parser.ensure_complete_parse(allow_semi, |parser| {
203-
let token_str = parser.this_token_to_string();
204-
let msg = format!("macro expansion ignores token `{}` and any following", token_str);
205-
let span = parser.span;
206-
parser.diagnostic()
207-
.struct_span_err(span, &msg)
208-
.span_note(*macro_span, "caused by the macro expansion here")
209-
.emit();
210-
});
211-
}
212-
}
213-
214-
impl<'a> MacResult for TokResult<'a> {
215-
fn make_items(mut self: Box<Self>) -> Option<SmallVector<P<ast::Item>>> {
216-
if self.parser.sess.span_diagnostic.has_errors() {
217-
return Some(SmallVector::zero());
218-
}
219-
220-
let mut items = SmallVector::zero();
221-
loop {
222-
match self.parser.parse_item() {
223-
Ok(Some(item)) => items.push(item),
224-
Ok(None) => {
225-
self.ensure_complete_parse(false);
226-
return Some(items);
227-
}
228-
Err(mut e) => {
229-
e.emit();
230-
return Some(SmallVector::zero());
231-
}
232-
}
233-
}
234-
}
235-
236-
fn make_impl_items(mut self: Box<Self>) -> Option<SmallVector<ast::ImplItem>> {
237-
let mut items = SmallVector::zero();
238-
loop {
239-
if self.parser.token == token::Eof {
240-
break;
241-
}
242-
match self.parser.parse_impl_item() {
243-
Ok(item) => items.push(item),
244-
Err(mut e) => {
245-
e.emit();
246-
return Some(SmallVector::zero());
247-
}
248-
}
249-
}
250-
self.ensure_complete_parse(false);
251-
Some(items)
252-
}
253-
254-
fn make_trait_items(mut self: Box<Self>) -> Option<SmallVector<ast::TraitItem>> {
255-
let mut items = SmallVector::zero();
256-
loop {
257-
if self.parser.token == token::Eof {
258-
break;
259-
}
260-
match self.parser.parse_trait_item() {
261-
Ok(item) => items.push(item),
262-
Err(mut e) => {
263-
e.emit();
264-
return Some(SmallVector::zero());
265-
}
266-
}
267-
}
268-
self.ensure_complete_parse(false);
269-
Some(items)
270-
}
271-
272-
fn make_expr(mut self: Box<Self>) -> Option<P<ast::Expr>> {
273-
match self.parser.parse_expr() {
274-
Ok(e) => {
275-
self.ensure_complete_parse(true);
276-
Some(e)
277-
}
278-
Err(mut e) => {
279-
e.emit();
280-
Some(DummyResult::raw_expr(self.span))
281-
}
282-
}
283-
}
284-
285-
fn make_pat(mut self: Box<Self>) -> Option<P<ast::Pat>> {
286-
match self.parser.parse_pat() {
287-
Ok(e) => {
288-
self.ensure_complete_parse(false);
289-
Some(e)
290-
}
291-
Err(mut e) => {
292-
e.emit();
293-
Some(P(DummyResult::raw_pat(self.span)))
294-
}
295-
}
296-
}
297-
298-
fn make_stmts(mut self: Box<Self>) -> Option<SmallVector<ast::Stmt>> {
299-
let mut stmts = SmallVector::zero();
300-
loop {
301-
if self.parser.token == token::Eof {
302-
break;
303-
}
304-
match self.parser.parse_full_stmt(false) {
305-
Ok(Some(stmt)) => stmts.push(stmt),
306-
Ok(None) => { /* continue */ }
307-
Err(mut e) => {
308-
e.emit();
309-
return Some(SmallVector::zero());
310-
}
311-
}
312-
}
313-
self.ensure_complete_parse(false);
314-
Some(stmts)
315-
}
316-
317-
fn make_ty(mut self: Box<Self>) -> Option<P<ast::Ty>> {
318-
match self.parser.parse_ty() {
319-
Ok(e) => {
320-
self.ensure_complete_parse(false);
321-
Some(e)
322-
}
323-
Err(mut e) => {
324-
e.emit();
325-
Some(DummyResult::raw_ty(self.span))
326-
}
327-
}
328-
}
329-
}
330-
331190
/// Represents a thing that maps token trees to Macro Results
332191
pub trait TTMacroExpander {
333192
fn expand<'cx>(&self,

src/libsyntax/ext/expand.rs

+86-22
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// except according to those terms.
1010

1111
use ast::{Block, Crate, Ident, Mac_, PatKind};
12-
use ast::{MacStmtStyle, StmtKind, ItemKind};
12+
use ast::{Name, MacStmtStyle, StmtKind, ItemKind};
1313
use ast;
1414
use ext::hygiene::Mark;
1515
use ext::placeholders::{placeholder, PlaceholderExpander};
@@ -21,9 +21,9 @@ use ext::base::*;
2121
use feature_gate::{self, Features};
2222
use fold;
2323
use fold::*;
24-
use parse::{ParseSess, lexer};
24+
use parse::{ParseSess, PResult, lexer};
2525
use parse::parser::Parser;
26-
use parse::token::{intern, keywords};
26+
use parse::token::{self, intern, keywords};
2727
use print::pprust;
2828
use ptr::P;
2929
use tokenstream::{TokenTree, TokenStream};
@@ -38,12 +38,12 @@ macro_rules! expansions {
3838
($($kind:ident: $ty:ty [$($vec:ident, $ty_elt:ty)*], $kind_name:expr, .$make:ident,
3939
$(.$fold:ident)* $(lift .$fold_elt:ident)*,
4040
$(.$visit:ident)* $(lift .$visit_elt:ident)*;)*) => {
41-
#[derive(Copy, Clone)]
41+
#[derive(Copy, Clone, PartialEq, Eq)]
4242
pub enum ExpansionKind { OptExpr, $( $kind, )* }
4343
pub enum Expansion { OptExpr(Option<P<ast::Expr>>), $( $kind($ty), )* }
4444

4545
impl ExpansionKind {
46-
fn name(self) -> &'static str {
46+
pub fn name(self) -> &'static str {
4747
match self {
4848
ExpansionKind::OptExpr => "expression",
4949
$( ExpansionKind::$kind => $kind_name, )*
@@ -106,6 +106,12 @@ macro_rules! expansions {
106106
self.expand(Expansion::$kind(SmallVector::one(node))).$make()
107107
})*)*
108108
}
109+
110+
impl<'a> MacResult for ::ext::tt::macro_rules::ParserAnyMacro<'a> {
111+
$(fn $make(self: Box<::ext::tt::macro_rules::ParserAnyMacro<'a>>) -> Option<$ty> {
112+
Some(self.make(ExpansionKind::$kind).$make())
113+
})*
114+
}
109115
}
110116
}
111117

@@ -293,10 +299,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
293299
};
294300

295301
attr::mark_used(&attr);
302+
let name = intern(&attr.name());
296303
self.cx.bt_push(ExpnInfo {
297304
call_site: attr.span,
298305
callee: NameAndSpan {
299-
format: MacroAttribute(intern(&attr.name())),
306+
format: MacroAttribute(name),
300307
span: Some(attr.span),
301308
allow_internal_unstable: false,
302309
}
@@ -319,14 +326,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
319326
let item_toks = TokenStream::from_tts(tts_for_item(&item, &self.cx.parse_sess));
320327

321328
let tok_result = mac.expand(self.cx, attr.span, attr_toks, item_toks);
322-
let parser = self.cx.new_parser_from_tts(&tok_result.to_tts());
323-
let result = Box::new(TokResult { parser: parser, span: attr.span });
324-
325-
kind.make_from(result).unwrap_or_else(|| {
326-
let msg = format!("macro could not be expanded into {} position", kind.name());
327-
self.cx.span_err(attr.span, &msg);
328-
kind.dummy(attr.span)
329-
})
329+
self.parse_expansion(tok_result, kind, name, attr.span)
330330
}
331331
_ => unreachable!(),
332332
}
@@ -423,14 +423,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
423423
},
424424
});
425425

426-
427-
let tok_result = expandfun.expand(self.cx,
428-
span,
429-
TokenStream::from_tts(marked_tts));
430-
let parser = self.cx.new_parser_from_tts(&tok_result.to_tts());
431-
let result = Box::new(TokResult { parser: parser, span: span });
432-
// FIXME better span info.
433-
kind.make_from(result).map(|i| i.fold_with(&mut ChangeSpan { span: span }))
426+
let toks = TokenStream::from_tts(marked_tts);
427+
let tok_result = expandfun.expand(self.cx, span, toks);
428+
Some(self.parse_expansion(tok_result, kind, extname, span))
434429
}
435430
};
436431

@@ -448,6 +443,75 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
448443
expn_id: Some(self.cx.backtrace()),
449444
})
450445
}
446+
447+
fn parse_expansion(&mut self, toks: TokenStream, kind: ExpansionKind, name: Name, span: Span)
448+
-> Expansion {
449+
let mut parser = self.cx.new_parser_from_tts(&toks.to_tts());
450+
let expansion = match parser.parse_expansion(kind, false) {
451+
Ok(expansion) => expansion,
452+
Err(mut err) => {
453+
err.emit();
454+
return kind.dummy(span);
455+
}
456+
};
457+
parser.ensure_complete_parse(name, kind.name(), span);
458+
// FIXME better span info
459+
expansion.fold_with(&mut ChangeSpan { span: span })
460+
}
461+
}
462+
463+
impl<'a> Parser<'a> {
464+
pub fn parse_expansion(&mut self, kind: ExpansionKind, macro_legacy_warnings: bool)
465+
-> PResult<'a, Expansion> {
466+
Ok(match kind {
467+
ExpansionKind::Items => {
468+
let mut items = SmallVector::zero();
469+
while let Some(item) = self.parse_item()? {
470+
items.push(item);
471+
}
472+
Expansion::Items(items)
473+
}
474+
ExpansionKind::TraitItems => {
475+
let mut items = SmallVector::zero();
476+
while self.token != token::Eof {
477+
items.push(self.parse_trait_item()?);
478+
}
479+
Expansion::TraitItems(items)
480+
}
481+
ExpansionKind::ImplItems => {
482+
let mut items = SmallVector::zero();
483+
while self.token != token::Eof {
484+
items.push(self.parse_impl_item()?);
485+
}
486+
Expansion::ImplItems(items)
487+
}
488+
ExpansionKind::Stmts => {
489+
let mut stmts = SmallVector::zero();
490+
while self.token != token::Eof {
491+
if let Some(stmt) = self.parse_full_stmt(macro_legacy_warnings)? {
492+
stmts.push(stmt);
493+
}
494+
}
495+
Expansion::Stmts(stmts)
496+
}
497+
ExpansionKind::Expr => Expansion::Expr(self.parse_expr()?),
498+
ExpansionKind::OptExpr => Expansion::OptExpr(Some(self.parse_expr()?)),
499+
ExpansionKind::Ty => Expansion::Ty(self.parse_ty()?),
500+
ExpansionKind::Pat => Expansion::Pat(self.parse_pat()?),
501+
})
502+
}
503+
504+
pub fn ensure_complete_parse(&mut self, macro_name: ast::Name, kind_name: &str, span: Span) {
505+
if self.token != token::Eof {
506+
let msg = format!("macro expansion ignores token `{}` and any following",
507+
self.this_token_to_string());
508+
let mut err = self.diagnostic().struct_span_err(self.span, &msg);
509+
let msg = format!("caused by the macro expansion here; the usage \
510+
of `{}!` is likely invalid in {} context",
511+
macro_name, kind_name);
512+
err.span_note(span, &msg).emit();
513+
}
514+
}
451515
}
452516

453517
struct InvocationCollector<'a, 'b: 'a> {

0 commit comments

Comments
 (0)