Skip to content

Commit 3277a06

Browse files
committed
undo rust-lang#49719 for rust 2015 with feature flag
1 parent 29f48cc commit 3277a06

File tree

2 files changed

+83
-51
lines changed

2 files changed

+83
-51
lines changed

src/libsyntax/ext/tt/macro_rules.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,14 @@ pub fn compile(sess: &ParseSess, features: &Features, def: &ast::Item, edition:
240240
s.iter().map(|m| {
241241
if let MatchedNonterminal(ref nt) = *m {
242242
if let NtTT(ref tt) = **nt {
243-
let tt = quoted::parse(tt.clone().into(), true, sess, features, &def.attrs)
244-
.pop().unwrap();
243+
let tt = quoted::parse(
244+
tt.clone().into(),
245+
true,
246+
sess,
247+
features,
248+
&def.attrs,
249+
edition
250+
).pop().unwrap();
245251
valid &= check_lhs_nt_follows(sess, features, &def.attrs, &tt);
246252
return tt;
247253
}
@@ -257,8 +263,14 @@ pub fn compile(sess: &ParseSess, features: &Features, def: &ast::Item, edition:
257263
s.iter().map(|m| {
258264
if let MatchedNonterminal(ref nt) = *m {
259265
if let NtTT(ref tt) = **nt {
260-
return quoted::parse(tt.clone().into(), false, sess, features, &def.attrs)
261-
.pop().unwrap();
266+
return quoted::parse(
267+
tt.clone().into(),
268+
false,
269+
sess,
270+
features,
271+
&def.attrs,
272+
edition
273+
).pop().unwrap();
262274
}
263275
}
264276
sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs")

src/libsyntax/ext/tt/quoted.rs

Lines changed: 67 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010

1111
use {ast, attr};
1212
use ext::tt::macro_parser;
13-
use feature_gate::{self, emit_feature_err, Features, GateIssue};
13+
use feature_gate::Features;
1414
use parse::{token, ParseSess};
1515
use print::pprust;
1616
use symbol::keywords;
17-
use syntax_pos::{BytePos, Span, DUMMY_SP};
17+
use syntax_pos::{BytePos, Span, DUMMY_SP, edition::Edition};
1818
use tokenstream;
1919

2020
use std::iter::Peekable;
@@ -184,6 +184,7 @@ pub fn parse(
184184
sess: &ParseSess,
185185
features: &Features,
186186
attrs: &[ast::Attribute],
187+
edition: Edition,
187188
) -> Vec<TokenTree> {
188189
// Will contain the final collection of `self::TokenTree`
189190
let mut result = Vec::new();
@@ -194,7 +195,7 @@ pub fn parse(
194195
while let Some(tree) = trees.next() {
195196
// Given the parsed tree, if there is a metavar and we are expecting matchers, actually
196197
// parse out the matcher (i.e. in `$id:ident` this would parse the `:` and `ident`).
197-
let tree = parse_tree(tree, &mut trees, expect_matchers, sess, features, attrs);
198+
let tree = parse_tree(tree, &mut trees, expect_matchers, sess, features, attrs, edition);
198199
match tree {
199200
TokenTree::MetaVar(start_sp, ident) if expect_matchers => {
200201
let span = match trees.next() {
@@ -252,6 +253,7 @@ fn parse_tree<I>(
252253
sess: &ParseSess,
253254
features: &Features,
254255
attrs: &[ast::Attribute],
256+
edition: Edition,
255257
) -> TokenTree
256258
where
257259
I: Iterator<Item = tokenstream::TokenTree>,
@@ -270,9 +272,23 @@ where
270272
sess.span_diagnostic.span_err(span, &msg);
271273
}
272274
// Parse the contents of the sequence itself
273-
let sequence = parse(delimited.tts.into(), expect_matchers, sess, features, attrs);
275+
let sequence = parse(
276+
delimited.tts.into(),
277+
expect_matchers,
278+
sess,
279+
features,
280+
attrs,
281+
edition,
282+
);
274283
// Get the Kleene operator and optional separator
275-
let (separator, op) = parse_sep_and_kleene_op(trees, span, sess, features, attrs);
284+
let (separator, op) = parse_sep_and_kleene_op(
285+
trees,
286+
span,
287+
sess,
288+
features,
289+
attrs,
290+
edition
291+
);
276292
// Count the number of captured "names" (i.e. named metavars)
277293
let name_captures = macro_parser::count_names(&sequence);
278294
TokenTree::Sequence(
@@ -322,19 +338,46 @@ where
322338
span,
323339
Lrc::new(Delimited {
324340
delim: delimited.delim,
325-
tts: parse(delimited.tts.into(), expect_matchers, sess, features, attrs),
341+
tts: parse(
342+
delimited.tts.into(),
343+
expect_matchers,
344+
sess,
345+
features,
346+
attrs,
347+
edition
348+
),
326349
}),
327350
),
328351
}
329352
}
330353

331354
/// Takes a token and returns `Some(KleeneOp)` if the token is `+` `*` or `?`. Otherwise, return
332-
/// `None`.
333-
fn kleene_op(token: &token::Token) -> Option<KleeneOp> {
355+
/// `None`. This function takes into account what edition and feature flags are enabled.
356+
fn kleene_op(
357+
token: &token::Token,
358+
span: Span,
359+
sess: &ParseSess,
360+
edition: Edition,
361+
features: &Features,
362+
attrs: &[ast::Attribute],
363+
) -> Option<KleeneOp> {
334364
match *token {
335365
token::BinOp(token::Star) => Some(KleeneOp::ZeroOrMore),
336366
token::BinOp(token::Plus) => Some(KleeneOp::OneOrMore),
337-
token::Question => Some(KleeneOp::ZeroOrOne),
367+
token::Question =>
368+
if edition >= Edition::Edition2018
369+
|| (features.macro_at_most_once_rep
370+
&& attr::contains_name(attrs, "allow_internal_unstable")) {
371+
Some(KleeneOp::ZeroOrOne)
372+
} else {
373+
sess.span_diagnostic
374+
.span_warn(
375+
span,
376+
"`?` as a separator is deprecated and \
377+
will be removed in an upcoming edition."
378+
);
379+
None
380+
},
338381
_ => None,
339382
}
340383
}
@@ -347,14 +390,20 @@ fn kleene_op(token: &token::Token) -> Option<KleeneOp> {
347390
fn parse_kleene_op<I>(
348391
input: &mut I,
349392
span: Span,
393+
sess: &ParseSess,
394+
edition: Edition,
395+
features: &Features,
396+
attrs: &[ast::Attribute],
350397
) -> Result<Result<KleeneOp, (token::Token, Span)>, Span>
351398
where
352399
I: Iterator<Item = tokenstream::TokenTree>,
353400
{
354401
match input.next() {
355-
Some(tokenstream::TokenTree::Token(span, tok)) => match kleene_op(&tok) {
356-
Some(op) => Ok(Ok(op)),
357-
None => Ok(Err((tok, span))),
402+
Some(tokenstream::TokenTree::Token(span, tok)) => {
403+
match kleene_op(&tok, span, sess, edition, features, attrs) {
404+
Some(op) => Ok(Ok(op)),
405+
None => Ok(Err((tok, span))),
406+
}
358407
},
359408
tree => Err(tree.as_ref()
360409
.map(tokenstream::TokenTree::span)
@@ -380,51 +429,22 @@ fn parse_sep_and_kleene_op<I>(
380429
sess: &ParseSess,
381430
features: &Features,
382431
attrs: &[ast::Attribute],
432+
edition: Edition,
383433
) -> (Option<token::Token>, KleeneOp)
384434
where
385435
I: Iterator<Item = tokenstream::TokenTree>,
386436
{
387437
// We basically look at two token trees here, denoted as #1 and #2 below
388-
let span = match parse_kleene_op(input, span) {
389-
// #1 is any KleeneOp (`?`)
390-
Ok(Ok(op)) if op == KleeneOp::ZeroOrOne => {
391-
if !features.macro_at_most_once_rep
392-
&& !attr::contains_name(attrs, "allow_internal_unstable")
393-
{
394-
let explain = feature_gate::EXPLAIN_MACRO_AT_MOST_ONCE_REP;
395-
emit_feature_err(
396-
sess,
397-
"macro_at_most_once_rep",
398-
span,
399-
GateIssue::Language,
400-
explain,
401-
);
402-
}
403-
return (None, op);
404-
}
405-
406-
// #1 is any KleeneOp (`+`, `*`)
438+
let span = match parse_kleene_op(input, span, sess, edition, features, attrs) {
439+
// #1 is any KleeneOp (`+`, `*`, or `?` (on editions > 2015))
407440
Ok(Ok(op)) => return (None, op),
408441

409442
// #1 is a separator followed by #2, a KleeneOp
410-
Ok(Err((tok, span))) => match parse_kleene_op(input, span) {
443+
Ok(Err((tok, span))) => match parse_kleene_op(input, span, sess, edition, features, attrs) {
411444
// #2 is a KleeneOp :D
412445
Ok(Ok(op)) if op == KleeneOp::ZeroOrOne => {
413-
if !features.macro_at_most_once_rep
414-
&& !attr::contains_name(attrs, "allow_internal_unstable")
415-
{
416-
let explain = feature_gate::EXPLAIN_MACRO_AT_MOST_ONCE_REP;
417-
emit_feature_err(
418-
sess,
419-
"macro_at_most_once_rep",
420-
span,
421-
GateIssue::Language,
422-
explain,
423-
);
424-
} else {
425-
sess.span_diagnostic
426-
.span_err(span, "`?` macro repetition does not allow a separator");
427-
}
446+
sess.span_diagnostic
447+
.span_err(span, "`?` macro repetition does not allow a separator");
428448
return (None, op);
429449
}
430450
Ok(Ok(op)) => return (Some(tok), op),

0 commit comments

Comments
 (0)