diff options
| author | Mark Mansi <markm@cs.wisc.edu> | 2018-04-05 19:50:08 -0500 |
|---|---|---|
| committer | Mark Mansi <markm@cs.wisc.edu> | 2018-04-05 19:50:08 -0500 |
| commit | b2ed17b5ea8d300838138844e3b2701cf000eae2 (patch) | |
| tree | 4901f970d866136290ed8d70404d132eea51197c /src/libsyntax | |
| parent | 56714acc5eb0687ed9a7566fdebe5528657fc5b3 (diff) | |
| download | rust-b2ed17b5ea8d300838138844e3b2701cf000eae2.tar.gz rust-b2ed17b5ea8d300838138844e3b2701cf000eae2.zip | |
No separator for `?`. No `?` as a separator.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ext/tt/quoted.rs | 89 |
1 files changed, 22 insertions, 67 deletions
diff --git a/src/libsyntax/ext/tt/quoted.rs b/src/libsyntax/ext/tt/quoted.rs index f324edeb117..30b993dda3d 100644 --- a/src/libsyntax/ext/tt/quoted.rs +++ b/src/libsyntax/ext/tt/quoted.rs @@ -389,72 +389,26 @@ where { // We basically look at two token trees here, denoted as #1 and #2 below let span = match parse_kleene_op(input, span) { - // #1 is a `+` or `*` KleeneOp - // - // `?` is ambiguous: it could be a separator or a Kleene::ZeroOrOne, so we need to look - // ahead one more token to be sure. - Ok(Ok(op)) if op != KleeneOp::ZeroOrOne => return (None, op), - - // #1 is `?` token, but it could be a Kleene::ZeroOrOne without a separator or it could - // be a `?` separator followed by any Kleene operator. We need to look ahead 1 token to - // find out which. - Ok(Ok(op)) => { - assert_eq!(op, KleeneOp::ZeroOrOne); - - // Lookahead at #2. If it is a KleenOp, then #1 is a separator. - let is_1_sep = if let Some(&tokenstream::TokenTree::Token(_, ref tok2)) = input.peek() { - kleene_op(tok2).is_some() - } else { - false - }; - - if is_1_sep { - // #1 is a separator and #2 should be a KleepeOp::* - // (N.B. We need to advance the input iterator.) - match parse_kleene_op(input, span) { - // #2 is a KleeneOp (this is the only valid option) :) - Ok(Ok(op)) if op == KleeneOp::ZeroOrOne => { - if !features.macro_at_most_once_rep - && !attr::contains_name(attrs, "allow_internal_unstable") - { - let explain = feature_gate::EXPLAIN_MACRO_AT_MOST_ONCE_REP; - emit_feature_err( - sess, - "macro_at_most_once_rep", - span, - GateIssue::Language, - explain, - ); - } - return (Some(token::Question), op); - } - Ok(Ok(op)) => return (Some(token::Question), op), - - // #2 is a random token (this is an error) :( - Ok(Err((_, span))) => span, - - // #2 is not even a token at all :( - Err(span) => span, - } - } else { - if !features.macro_at_most_once_rep - && !attr::contains_name(attrs, "allow_internal_unstable") - { - let explain = feature_gate::EXPLAIN_MACRO_AT_MOST_ONCE_REP; - emit_feature_err( - sess, - "macro_at_most_once_rep", - span, - GateIssue::Language, - explain, - ); - } - - // #2 is a random tree and #1 is KleeneOp::ZeroOrOne - return (None, op); + // #1 is any KleeneOp (`?`) + Ok(Ok(op)) if op == KleeneOp::ZeroOrOne => { + if !features.macro_at_most_once_rep + && !attr::contains_name(attrs, "allow_internal_unstable") + { + let explain = feature_gate::EXPLAIN_MACRO_AT_MOST_ONCE_REP; + emit_feature_err( + sess, + "macro_at_most_once_rep", + span, + GateIssue::Language, + explain, + ); } + return (None, op); } + // #1 is any KleeneOp (`+`, `*`) + Ok(Ok(op)) => return (None, op), + // #1 is a separator followed by #2, a KleeneOp Ok(Err((tok, span))) => match parse_kleene_op(input, span) { // #2 is a KleeneOp :D @@ -470,8 +424,11 @@ where GateIssue::Language, explain, ); + } else { + sess.span_diagnostic + .span_err(span, "`?` macro repetition does not allow a separator"); } - return (Some(tok), op); + return (None, op); } Ok(Ok(op)) => return (Some(tok), op), @@ -486,9 +443,7 @@ where Err(span) => span, }; - if !features.macro_at_most_once_rep - && !attr::contains_name(attrs, "allow_internal_unstable") - { + if !features.macro_at_most_once_rep && !attr::contains_name(attrs, "allow_internal_unstable") { sess.span_diagnostic .span_err(span, "expected one of: `*`, `+`, or `?`"); } else { |
