Skip to content

Commit 92dd995

Browse files
committed
Auto merge of #23331 - eddyb:attr-lookahead, r=nikomatsakis
Most of the changes are cleanup facilitated by straight-forward attribute handling. This is a minor [breaking-change] for users of `quote_stmt!` (returns `Option<P<Stmt>>` now) and some of the public methods in `Parser` (a few `Vec<Attribute>` arguments/returns were removed). r? @nikomatsakis
2 parents 1760e87 + 9889aae commit 92dd995

File tree

11 files changed

+323
-510
lines changed

11 files changed

+323
-510
lines changed

src/libsyntax/ext/quote.rs

+4-8
Original file line numberDiff line numberDiff line change
@@ -361,8 +361,7 @@ pub mod rt {
361361
parse::parse_stmt_from_source_str("<quote expansion>".to_string(),
362362
s,
363363
self.cfg(),
364-
Vec::new(),
365-
self.parse_sess())
364+
self.parse_sess()).expect("parse error")
366365
}
367366

368367
fn parse_expr(&self, s: String) -> P<ast::Expr> {
@@ -407,16 +406,15 @@ pub fn expand_quote_expr<'cx>(cx: &'cx mut ExtCtxt,
407406
sp: Span,
408407
tts: &[ast::TokenTree])
409408
-> Box<base::MacResult+'cx> {
410-
let expanded = expand_parse_call(cx, sp, "parse_expr", Vec::new(), tts);
409+
let expanded = expand_parse_call(cx, sp, "parse_expr", vec!(), tts);
411410
base::MacEager::expr(expanded)
412411
}
413412

414413
pub fn expand_quote_item<'cx>(cx: &mut ExtCtxt,
415414
sp: Span,
416415
tts: &[ast::TokenTree])
417416
-> Box<base::MacResult+'cx> {
418-
let expanded = expand_parse_call(cx, sp, "parse_item_with_outer_attributes",
419-
vec!(), tts);
417+
let expanded = expand_parse_call(cx, sp, "parse_item", vec!(), tts);
420418
base::MacEager::expr(expanded)
421419
}
422420

@@ -448,9 +446,7 @@ pub fn expand_quote_stmt(cx: &mut ExtCtxt,
448446
sp: Span,
449447
tts: &[ast::TokenTree])
450448
-> Box<base::MacResult+'static> {
451-
let e_attrs = cx.expr_vec_ng(sp);
452-
let expanded = expand_parse_call(cx, sp, "parse_stmt",
453-
vec!(e_attrs), tts);
449+
let expanded = expand_parse_call(cx, sp, "parse_stmt", vec!(), tts);
454450
base::MacEager::expr(expanded)
455451
}
456452

src/libsyntax/ext/source_util.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree
115115
-> Option<SmallVector<P<ast::Item>>> {
116116
let mut ret = SmallVector::zero();
117117
while self.p.token != token::Eof {
118-
match self.p.parse_item_with_outer_attributes() {
118+
match self.p.parse_item() {
119119
Some(item) => ret.push(item),
120120
None => self.p.span_fatal(
121121
self.p.span,

src/libsyntax/ext/tt/macro_parser.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -521,12 +521,15 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal {
521521
// check at the beginning and the parser checks after each bump
522522
p.check_unknown_macro_variable();
523523
match name {
524-
"item" => match p.parse_item(Vec::new()) {
524+
"item" => match p.parse_item() {
525525
Some(i) => token::NtItem(i),
526526
None => p.fatal("expected an item keyword")
527527
},
528528
"block" => token::NtBlock(p.parse_block()),
529-
"stmt" => token::NtStmt(p.parse_stmt(Vec::new())),
529+
"stmt" => match p.parse_stmt() {
530+
Some(s) => token::NtStmt(s),
531+
None => p.fatal("expected a statement")
532+
},
530533
"pat" => token::NtPat(p.parse_pat()),
531534
"expr" => token::NtExpr(p.parse_expr()),
532535
"ty" => token::NtTy(p.parse_ty()),

src/libsyntax/ext/tt/macro_rules.rs

+5-14
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal};
1717
use ext::tt::macro_parser::{parse, parse_or_else};
1818
use parse::lexer::new_tt_reader;
1919
use parse::parser::Parser;
20-
use parse::attr::ParserAttr;
2120
use parse::token::{self, special_idents, gensym_ident, NtTT, Token};
2221
use parse::token::Token::*;
2322
use print;
@@ -68,15 +67,8 @@ impl<'a> MacResult for ParserAnyMacro<'a> {
6867
}
6968
fn make_items(self: Box<ParserAnyMacro<'a>>) -> Option<SmallVector<P<ast::Item>>> {
7069
let mut ret = SmallVector::zero();
71-
loop {
72-
let mut parser = self.parser.borrow_mut();
73-
// so... do outer attributes attached to the macro invocation
74-
// just disappear? This question applies to make_impl_items, as
75-
// well.
76-
match parser.parse_item_with_outer_attributes() {
77-
Some(item) => ret.push(item),
78-
None => break
79-
}
70+
while let Some(item) = self.parser.borrow_mut().parse_item() {
71+
ret.push(item);
8072
}
8173
self.ensure_complete_parse(false);
8274
Some(ret)
@@ -89,18 +81,17 @@ impl<'a> MacResult for ParserAnyMacro<'a> {
8981
let mut parser = self.parser.borrow_mut();
9082
match parser.token {
9183
token::Eof => break,
92-
_ => ret.push(parser.parse_impl_item_with_outer_attributes())
84+
_ => ret.push(parser.parse_impl_item())
9385
}
9486
}
9587
self.ensure_complete_parse(false);
9688
Some(ret)
9789
}
9890

9991
fn make_stmt(self: Box<ParserAnyMacro<'a>>) -> Option<P<ast::Stmt>> {
100-
let attrs = self.parser.borrow_mut().parse_outer_attributes();
101-
let ret = self.parser.borrow_mut().parse_stmt(attrs);
92+
let ret = self.parser.borrow_mut().parse_stmt();
10293
self.ensure_complete_parse(true);
103-
Some(ret)
94+
ret
10495
}
10596
}
10697

src/libsyntax/parse/attr.rs

+26-32
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,8 @@ use ptr::P;
1919
/// A parser that can parse attributes.
2020
pub trait ParserAttr {
2121
fn parse_outer_attributes(&mut self) -> Vec<ast::Attribute>;
22+
fn parse_inner_attributes(&mut self) -> Vec<ast::Attribute>;
2223
fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute;
23-
fn parse_inner_attrs_and_next(&mut self)
24-
-> (Vec<ast::Attribute>, Vec<ast::Attribute>);
2524
fn parse_meta_item(&mut self) -> P<ast::MetaItem>;
2625
fn parse_meta_seq(&mut self) -> Vec<P<ast::MetaItem>>;
2726
fn parse_optional_meta(&mut self) -> Vec<P<ast::MetaItem>>;
@@ -118,45 +117,40 @@ impl<'a> ParserAttr for Parser<'a> {
118117

119118
/// Parse attributes that appear after the opening of an item. These should
120119
/// be preceded by an exclamation mark, but we accept and warn about one
121-
/// terminated by a semicolon. In addition to a vector of inner attributes,
122-
/// this function also returns a vector that may contain the first outer
123-
/// attribute of the next item (since we can't know whether the attribute
124-
/// is an inner attribute of the containing item or an outer attribute of
125-
/// the first contained item until we see the semi).
126-
127-
/// matches inner_attrs* outer_attr?
128-
/// you can make the 'next' field an Option, but the result is going to be
129-
/// more useful as a vector.
130-
fn parse_inner_attrs_and_next(&mut self)
131-
-> (Vec<ast::Attribute> , Vec<ast::Attribute> ) {
132-
let mut inner_attrs: Vec<ast::Attribute> = Vec::new();
133-
let mut next_outer_attrs: Vec<ast::Attribute> = Vec::new();
120+
/// terminated by a semicolon.
121+
122+
/// matches inner_attrs*
123+
fn parse_inner_attributes(&mut self) -> Vec<ast::Attribute> {
124+
let mut attrs: Vec<ast::Attribute> = vec![];
134125
loop {
135-
let attr = match self.token {
126+
match self.token {
136127
token::Pound => {
137-
self.parse_attribute(true)
128+
// Don't even try to parse if it's not an inner attribute.
129+
if !self.look_ahead(1, |t| t == &token::Not) {
130+
break;
131+
}
132+
133+
let attr = self.parse_attribute(true);
134+
assert!(attr.node.style == ast::AttrInner);
135+
attrs.push(attr);
138136
}
139137
token::DocComment(s) => {
140138
// we need to get the position of this token before we bump.
141139
let Span { lo, hi, .. } = self.span;
142-
self.bump();
143-
attr::mk_sugared_doc_attr(attr::mk_attr_id(),
144-
self.id_to_interned_str(s.ident()),
145-
lo,
146-
hi)
147-
}
148-
_ => {
149-
break;
140+
let attr = attr::mk_sugared_doc_attr(attr::mk_attr_id(),
141+
self.id_to_interned_str(s.ident()),
142+
lo, hi);
143+
if attr.node.style == ast::AttrInner {
144+
attrs.push(attr);
145+
self.bump();
146+
} else {
147+
break;
148+
}
150149
}
151-
};
152-
if attr.node.style == ast::AttrInner {
153-
inner_attrs.push(attr);
154-
} else {
155-
next_outer_attrs.push(attr);
156-
break;
150+
_ => break
157151
}
158152
}
159-
(inner_attrs, next_outer_attrs)
153+
attrs
160154
}
161155

162156
/// matches meta_item = IDENT

src/libsyntax/parse/mod.rs

+5-9
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,7 @@ pub fn parse_crate_attrs_from_file(
9696
cfg: ast::CrateConfig,
9797
sess: &ParseSess
9898
) -> Vec<ast::Attribute> {
99-
let mut parser = new_parser_from_file(sess, cfg, input);
100-
let (inner, _) = parser.parse_inner_attrs_and_next();
101-
inner
99+
new_parser_from_file(sess, cfg, input).parse_inner_attributes()
102100
}
103101

104102
pub fn parse_crate_from_source_str(name: String,
@@ -122,8 +120,7 @@ pub fn parse_crate_attrs_from_source_str(name: String,
122120
cfg,
123121
name,
124122
source);
125-
let (inner, _) = maybe_aborted(p.parse_inner_attrs_and_next(),p);
126-
inner
123+
maybe_aborted(p.parse_inner_attributes(), p)
127124
}
128125

129126
pub fn parse_expr_from_source_str(name: String,
@@ -141,7 +138,7 @@ pub fn parse_item_from_source_str(name: String,
141138
sess: &ParseSess)
142139
-> Option<P<ast::Item>> {
143140
let mut p = new_parser_from_source_str(sess, cfg, name, source);
144-
maybe_aborted(p.parse_item_with_outer_attributes(),p)
141+
maybe_aborted(p.parse_item(),p)
145142
}
146143

147144
pub fn parse_meta_from_source_str(name: String,
@@ -156,16 +153,15 @@ pub fn parse_meta_from_source_str(name: String,
156153
pub fn parse_stmt_from_source_str(name: String,
157154
source: String,
158155
cfg: ast::CrateConfig,
159-
attrs: Vec<ast::Attribute> ,
160156
sess: &ParseSess)
161-
-> P<ast::Stmt> {
157+
-> Option<P<ast::Stmt>> {
162158
let mut p = new_parser_from_source_str(
163159
sess,
164160
cfg,
165161
name,
166162
source
167163
);
168-
maybe_aborted(p.parse_stmt(attrs),p)
164+
maybe_aborted(p.parse_stmt(), p)
169165
}
170166

171167
// Note: keep in sync with `with_hygiene::parse_tts_from_source_str`

0 commit comments

Comments
 (0)