Auto merge of #56245 - mark-i-m:stabilize_ques_kleene, r=alexcrichton

Stabilize feature `macro_at_most_once_rep`

a.k.a. `?` Kleene operator 🎉

cc #48075

r? @Centril
This commit is contained in:
bors 2018-11-29 06:44:12 +00:00
commit 5a03532ea9
24 changed files with 32 additions and 279 deletions

View file

@ -1,22 +0,0 @@
# `macro_at_most_once_rep`
NOTE: This feature is only available in the 2018 Edition.
The tracking issue for this feature is: #48075
With this feature gate enabled, one can use `?` as a Kleene operator meaning "0
or 1 repetitions" in a macro definition. Previously only `+` and `*` were allowed.
For example:
```rust,ignore
#![feature(macro_at_most_once_rep)]
macro_rules! foo {
(something $(,)?) // `?` indicates `,` is "optional"...
=> {}
}
```
------------------------

View file

@ -181,7 +181,6 @@ that warns about any item named `lintme`.
```rust,ignore
#![feature(plugin_registrar)]
#![feature(box_syntax, rustc_private)]
#![feature(macro_at_most_once_rep)]
extern crate syntax;

View file

@ -93,7 +93,6 @@
#![feature(never_type)]
#![feature(nll)]
#![feature(exhaustive_patterns)]
#![feature(macro_at_most_once_rep)]
#![feature(no_core)]
#![feature(on_unimplemented)]
#![feature(optin_builtin_traits)]

View file

@ -67,7 +67,6 @@
#![feature(integer_atomics)]
#![feature(test)]
#![feature(in_band_lifetimes)]
#![feature(macro_at_most_once_rep)]
#![feature(crate_visibility_modifier)]
#![feature(transpose_result)]

View file

@ -29,7 +29,6 @@
#![feature(nll)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
#![feature(macro_at_most_once_rep)]
#[macro_use]
extern crate syntax;

View file

@ -14,7 +14,6 @@
#![feature(box_patterns)]
#![feature(libc)]
#![feature(macro_at_most_once_rep)]
#![feature(nll)]
#![feature(proc_macro_internals)]
#![feature(proc_macro_quote)]

View file

@ -11,13 +11,13 @@
use ast::NodeId;
use early_buffered_lints::BufferedEarlyLintId;
use ext::tt::macro_parser;
use feature_gate::{self, emit_feature_err, Features, GateIssue};
use feature_gate::Features;
use parse::{token, ParseSess};
use print::pprust;
use symbol::keywords;
use syntax_pos::{edition::Edition, BytePos, Span};
use tokenstream::{self, DelimSpan};
use {ast, attr};
use ast;
use rustc_data_structures::sync::Lrc;
use std::iter::Peekable;
@ -566,8 +566,8 @@ fn parse_sep_and_kleene_op_2018<I>(
input: &mut Peekable<I>,
span: Span,
sess: &ParseSess,
features: &Features,
attrs: &[ast::Attribute],
_features: &Features,
_attrs: &[ast::Attribute],
) -> (Option<token::Token>, KleeneOp)
where
I: Iterator<Item = tokenstream::TokenTree>,
@ -575,23 +575,8 @@ 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 `?` (needs feature gate)
Ok(Ok((op, op1_span))) 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",
op1_span,
GateIssue::Language,
explain,
);
op1_span
} else {
return (None, op);
}
Ok(Ok((op, _op1_span))) if op == KleeneOp::ZeroOrOne => {
return (None, op);
}
// #1 is a `+` or `*` KleeneOp
@ -600,24 +585,12 @@ where
// #1 is a separator followed by #2, a KleeneOp
Ok(Err((tok, span))) => match parse_kleene_op(input, span) {
// #2 is the `?` Kleene op, which does not take a separator (error)
Ok(Ok((op, op2_span))) if op == KleeneOp::ZeroOrOne => {
Ok(Ok((op, _op2_span))) if op == KleeneOp::ZeroOrOne => {
// Error!
if !features.macro_at_most_once_rep
&& !attr::contains_name(attrs, "allow_internal_unstable")
{
// FIXME: when `?` as a Kleene op is stabilized, we only need the "does not
// take a macro separator" error (i.e. the `else` case).
sess.span_diagnostic
.struct_span_err(op2_span, "expected `*` or `+`")
.note("`?` is not a macro repetition operator")
.emit();
} else {
sess.span_diagnostic.span_err(
span,
"the `?` macro repetition operator does not take a separator",
);
}
sess.span_diagnostic.span_err(
span,
"the `?` macro repetition operator does not take a separator",
);
// Return a dummy
return (None, KleeneOp::ZeroOrMore);
@ -638,13 +611,8 @@ where
};
// If we ever get to this point, we have experienced an "unexpected token" error
if !features.macro_at_most_once_rep && !attr::contains_name(attrs, "allow_internal_unstable") {
sess.span_diagnostic.span_err(span, "expected `*` or `+`");
} else {
sess.span_diagnostic
.span_err(span, "expected one of: `*`, `+`, or `?`");
}
sess.span_diagnostic
.span_err(span, "expected one of: `*`, `+`, or `?`");
// Return a dummy
(None, KleeneOp::ZeroOrMore)

View file

@ -393,9 +393,6 @@ declare_features! (
// `extern` in paths
(active, extern_in_paths, "1.23.0", Some(55600), None),
// Use `?` as the Kleene "at most one" operator
(active, macro_at_most_once_rep, "1.25.0", Some(48075), None),
// Infer static outlives requirements; RFC 2093
(active, infer_static_outlives_requirements, "1.26.0", Some(54185), None),
@ -689,6 +686,8 @@ declare_features! (
(accepted, extern_crate_item_prelude, "1.31.0", Some(55599), None),
// Allows use of the :literal macro fragment specifier (RFC 1576)
(accepted, macro_literal_matcher, "1.31.0", Some(35625), None),
// Use `?` as the Kleene "at most one" operator
(accepted, macro_at_most_once_rep, "1.32.0", Some(48075), None),
);
// If you change this, please modify src/doc/unstable-book as well. You must
@ -1427,9 +1426,6 @@ pub const EXPLAIN_DERIVE_UNDERSCORE: &'static str =
pub const EXPLAIN_UNSIZED_TUPLE_COERCION: &'static str =
"unsized tuple coercion is not stable enough for use and is subject to change";
pub const EXPLAIN_MACRO_AT_MOST_ONCE_REP: &'static str =
"using the `?` macro Kleene operator for \"at most one\" repetition is unstable";
struct PostExpansionVisitor<'a> {
context: &'a Context<'a>,
}

View file

@ -20,7 +20,6 @@
test(attr(deny(warnings))))]
#![feature(crate_visibility_modifier)]
#![feature(macro_at_most_once_rep)]
#![feature(nll)]
#![feature(rustc_attrs)]
#![feature(rustc_diagnostic_macros)]

View file

@ -12,7 +12,6 @@
#![feature(plugin_registrar, rustc_private)]
#![feature(box_syntax)]
#![feature(macro_at_most_once_rep)]
#[macro_use] extern crate rustc;
extern crate rustc_plugin;

View file

@ -12,7 +12,6 @@
#![feature(plugin_registrar)]
#![feature(box_syntax, rustc_private)]
#![feature(macro_at_most_once_rep)]
// Load rustc as a plugin to get macros
#[macro_use]

View file

@ -12,7 +12,6 @@
#![feature(plugin_registrar)]
#![feature(box_syntax, rustc_private)]
#![feature(macro_at_most_once_rep)]
extern crate syntax;

View file

@ -12,7 +12,6 @@
#![feature(plugin_registrar, rustc_private)]
#![feature(box_syntax)]
#![feature(macro_at_most_once_rep)]
#[macro_use] extern crate rustc;
extern crate rustc_plugin;

View file

@ -9,7 +9,6 @@
// except according to those terms.
#![feature(box_syntax, plugin, plugin_registrar, rustc_private)]
#![feature(macro_at_most_once_rep)]
#![crate_type = "dylib"]
#[macro_use]

View file

@ -22,8 +22,6 @@
// edition:2018
#![feature(macro_at_most_once_rep)]
macro_rules! foo {
($($a:ident)? ; $num:expr) => { {
let mut x = 0;

View file

@ -12,7 +12,6 @@
#![feature(plugin_registrar)]
#![feature(box_syntax, rustc_private)]
#![feature(macro_at_most_once_rep)]
// Load rustc as a plugin to get macros
#[macro_use]

View file

@ -12,7 +12,6 @@
#![feature(plugin_registrar)]
#![feature(box_syntax, rustc_private)]
#![feature(macro_at_most_once_rep)]
extern crate syntax;

View file

@ -10,7 +10,6 @@
#![feature(plugin_registrar)]
#![feature(box_syntax, rustc_private)]
#![feature(macro_at_most_once_rep)]
extern crate syntax;

View file

@ -1,28 +0,0 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Test behavior of `?` macro _kleene op_ under the 2015 edition. Namely, it doesn't exist, even
// with the feature flag.
// gate-test-macro_at_most_once_rep
// edition:2015
#![feature(macro_at_most_once_rep)]
macro_rules! bar {
($(a)?) => {} //~ERROR expected `*` or `+`
}
macro_rules! baz {
($(a),?) => {} //~ERROR expected `*` or `+`
}
fn main() {}

View file

@ -1,18 +0,0 @@
error: expected `*` or `+`
--> $DIR/macro-at-most-once-rep-2015-ques-rep-feature-flag.rs:20:10
|
LL | ($(a)?) => {} //~ERROR expected `*` or `+`
| ^
|
= note: `?` is not a macro repetition operator
error: expected `*` or `+`
--> $DIR/macro-at-most-once-rep-2015-ques-rep-feature-flag.rs:24:11
|
LL | ($(a),?) => {} //~ERROR expected `*` or `+`
| ^
|
= note: `?` is not a macro repetition operator
error: aborting due to 2 previous errors

View file

@ -1,45 +0,0 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Feature gate test for macro_at_most_once_rep under 2018 edition.
// gate-test-macro_at_most_once_rep
// edition:2018
macro_rules! foo {
($(a)?) => {}
//~^ERROR using the `?` macro Kleene operator for
//~|ERROR expected `*` or `+`
}
macro_rules! baz {
($(a),?) => {} //~ERROR expected `*` or `+`
}
macro_rules! barplus {
($(a)?+) => {}
//~^ERROR using the `?` macro Kleene operator for
//~|ERROR expected `*` or `+`
}
macro_rules! barstar {
($(a)?*) => {}
//~^ERROR using the `?` macro Kleene operator for
//~|ERROR expected `*` or `+`
}
pub fn main() {
foo!();
foo!(a);
foo!(a?); //~ ERROR no rules expected the token `?`
foo!(a?a); //~ ERROR no rules expected the token `?`
foo!(a?a?a); //~ ERROR no rules expected the token `?`
}

View file

@ -1,80 +0,0 @@
error[E0658]: using the `?` macro Kleene operator for "at most one" repetition is unstable (see issue #48075)
--> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:17:10
|
LL | ($(a)?) => {}
| ^
|
= help: add #![feature(macro_at_most_once_rep)] to the crate attributes to enable
error: expected `*` or `+`
--> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:17:10
|
LL | ($(a)?) => {}
| ^
error: expected `*` or `+`
--> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:23:11
|
LL | ($(a),?) => {} //~ERROR expected `*` or `+`
| ^
|
= note: `?` is not a macro repetition operator
error[E0658]: using the `?` macro Kleene operator for "at most one" repetition is unstable (see issue #48075)
--> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:27:10
|
LL | ($(a)?+) => {}
| ^
|
= help: add #![feature(macro_at_most_once_rep)] to the crate attributes to enable
error: expected `*` or `+`
--> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:27:10
|
LL | ($(a)?+) => {}
| ^
error[E0658]: using the `?` macro Kleene operator for "at most one" repetition is unstable (see issue #48075)
--> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:33:10
|
LL | ($(a)?*) => {}
| ^
|
= help: add #![feature(macro_at_most_once_rep)] to the crate attributes to enable
error: expected `*` or `+`
--> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:33:10
|
LL | ($(a)?*) => {}
| ^
error: no rules expected the token `?`
--> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:41:11
|
LL | macro_rules! foo {
| ---------------- when calling this macro
...
LL | foo!(a?); //~ ERROR no rules expected the token `?`
| ^ no rules expected this token in macro call
error: no rules expected the token `?`
--> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:42:11
|
LL | macro_rules! foo {
| ---------------- when calling this macro
...
LL | foo!(a?a); //~ ERROR no rules expected the token `?`
| ^ no rules expected this token in macro call
error: no rules expected the token `?`
--> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:43:11
|
LL | macro_rules! foo {
| ---------------- when calling this macro
...
LL | foo!(a?a?a); //~ ERROR no rules expected the token `?`
| ^ no rules expected this token in macro call
error: aborting due to 10 previous errors
For more information about this error, try `rustc --explain E0658`.

View file

@ -12,22 +12,20 @@
// edition:2018
#![feature(macro_at_most_once_rep)]
macro_rules! foo {
($(a)?) => {}
($(a)?) => {};
}
macro_rules! baz {
($(a),?) => {} //~ERROR the `?` macro repetition operator
($(a),?) => {}; //~ERROR the `?` macro repetition operator
}
macro_rules! barplus {
($(a)?+) => {} // ok. matches "a+" and "+"
($(a)?+) => {}; // ok. matches "a+" and "+"
}
macro_rules! barstar {
($(a)?*) => {} // ok. matches "a*" and "*"
($(a)?*) => {}; // ok. matches "a*" and "*"
}
pub fn main() {

View file

@ -1,11 +1,11 @@
error: the `?` macro repetition operator does not take a separator
--> $DIR/macro-at-most-once-rep-2018.rs:22:10
--> $DIR/macro-at-most-once-rep-2018.rs:20:10
|
LL | ($(a),?) => {} //~ERROR the `?` macro repetition operator
LL | ($(a),?) => {}; //~ERROR the `?` macro repetition operator
| ^
error: no rules expected the token `?`
--> $DIR/macro-at-most-once-rep-2018.rs:36:11
--> $DIR/macro-at-most-once-rep-2018.rs:34:11
|
LL | macro_rules! foo {
| ---------------- when calling this macro
@ -14,7 +14,7 @@ LL | foo!(a?); //~ ERROR no rules expected the token `?`
| ^ no rules expected this token in macro call
error: no rules expected the token `?`
--> $DIR/macro-at-most-once-rep-2018.rs:37:11
--> $DIR/macro-at-most-once-rep-2018.rs:35:11
|
LL | macro_rules! foo {
| ---------------- when calling this macro
@ -23,7 +23,7 @@ LL | foo!(a?a); //~ ERROR no rules expected the token `?`
| ^ no rules expected this token in macro call
error: no rules expected the token `?`
--> $DIR/macro-at-most-once-rep-2018.rs:38:11
--> $DIR/macro-at-most-once-rep-2018.rs:36:11
|
LL | macro_rules! foo {
| ---------------- when calling this macro
@ -32,7 +32,7 @@ LL | foo!(a?a?a); //~ ERROR no rules expected the token `?`
| ^ no rules expected this token in macro call
error: unexpected end of macro invocation
--> $DIR/macro-at-most-once-rep-2018.rs:40:5
--> $DIR/macro-at-most-once-rep-2018.rs:38:5
|
LL | macro_rules! barplus {
| -------------------- when calling this macro
@ -41,7 +41,7 @@ LL | barplus!(); //~ERROR unexpected end of macro invocation
| ^^^^^^^^^^^ missing tokens in macro arguments
error: unexpected end of macro invocation
--> $DIR/macro-at-most-once-rep-2018.rs:41:15
--> $DIR/macro-at-most-once-rep-2018.rs:39:15
|
LL | macro_rules! barplus {
| -------------------- when calling this macro
@ -50,7 +50,7 @@ LL | barplus!(a); //~ERROR unexpected end of macro invocation
| ^ missing tokens in macro arguments
error: no rules expected the token `?`
--> $DIR/macro-at-most-once-rep-2018.rs:42:15
--> $DIR/macro-at-most-once-rep-2018.rs:40:15
|
LL | macro_rules! barplus {
| -------------------- when calling this macro
@ -59,7 +59,7 @@ LL | barplus!(a?); //~ ERROR no rules expected the token `?`
| ^ no rules expected this token in macro call
error: no rules expected the token `?`
--> $DIR/macro-at-most-once-rep-2018.rs:43:15
--> $DIR/macro-at-most-once-rep-2018.rs:41:15
|
LL | macro_rules! barplus {
| -------------------- when calling this macro
@ -68,7 +68,7 @@ LL | barplus!(a?a); //~ ERROR no rules expected the token `?`
| ^ no rules expected this token in macro call
error: unexpected end of macro invocation
--> $DIR/macro-at-most-once-rep-2018.rs:47:5
--> $DIR/macro-at-most-once-rep-2018.rs:45:5
|
LL | macro_rules! barstar {
| -------------------- when calling this macro
@ -77,7 +77,7 @@ LL | barstar!(); //~ERROR unexpected end of macro invocation
| ^^^^^^^^^^^ missing tokens in macro arguments
error: unexpected end of macro invocation
--> $DIR/macro-at-most-once-rep-2018.rs:48:15
--> $DIR/macro-at-most-once-rep-2018.rs:46:15
|
LL | macro_rules! barstar {
| -------------------- when calling this macro
@ -86,7 +86,7 @@ LL | barstar!(a); //~ERROR unexpected end of macro invocation
| ^ missing tokens in macro arguments
error: no rules expected the token `?`
--> $DIR/macro-at-most-once-rep-2018.rs:49:15
--> $DIR/macro-at-most-once-rep-2018.rs:47:15
|
LL | macro_rules! barstar {
| -------------------- when calling this macro
@ -95,7 +95,7 @@ LL | barstar!(a?); //~ ERROR no rules expected the token `?`
| ^ no rules expected this token in macro call
error: no rules expected the token `?`
--> $DIR/macro-at-most-once-rep-2018.rs:50:15
--> $DIR/macro-at-most-once-rep-2018.rs:48:15
|
LL | macro_rules! barstar {
| -------------------- when calling this macro