) -> Option> {
@@ -254,63 +263,76 @@ pub trait MacResult {
/// By default this attempts to create an expression statement,
/// returning None if that fails.
fn make_stmt(self: Box) -> Option> {
- self.make_expr()
- .map(|e| P(codemap::respan(e.span, ast::StmtExpr(e, ast::DUMMY_NODE_ID))))
+ make_stmt_default!(self)
}
}
-/// A convenience type for macros that return a single expression.
-pub struct MacExpr {
- e: P
-}
-impl MacExpr {
- pub fn new(e: P) -> Box {
- box MacExpr { e: e } as Box
- }
-}
-impl MacResult for MacExpr {
- fn make_expr(self: Box) -> Option> {
- Some(self.e)
- }
- fn make_pat(self: Box) -> Option> {
- match self.e.node {
- ast::ExprLit(_) => Some(P(ast::Pat {
- id: ast::DUMMY_NODE_ID,
- span: self.e.span,
- node: ast::PatLit(self.e)
- })),
- _ => None
+macro_rules! make_MacEager {
+ ( $( $fld:ident: $t:ty, )* ) => {
+ /// `MacResult` implementation for the common case where you've already
+ /// built each form of AST that you might return.
+ #[derive(Default)]
+ pub struct MacEager {
+ $(
+ pub $fld: Option<$t>,
+ )*
+ }
+
+ impl MacEager {
+ $(
+ pub fn $fld(v: $t) -> Box {
+ box MacEager {
+ $fld: Some(v),
+ ..Default::default()
+ } as Box
+ }
+ )*
}
}
}
-/// A convenience type for macros that return a single pattern.
-pub struct MacPat {
- p: P
+
+make_MacEager! {
+ expr: P,
+ pat: P,
+ items: SmallVector>,
+ methods: SmallVector
>,
+ stmt: P,
}
-impl MacPat {
- pub fn new(p: P) -> Box {
- box MacPat { p: p } as Box
+
+impl MacResult for MacEager {
+ fn make_expr(self: Box) -> Option> {
+ self.expr
}
-}
-impl MacResult for MacPat {
- fn make_pat(self: Box) -> Option> {
- Some(self.p)
+
+ fn make_items(self: Box) -> Option>> {
+ self.items
}
-}
-/// A type for macros that return multiple items.
-pub struct MacItems {
- items: SmallVector>
-}
-impl MacItems {
- pub fn new>>(it: I) -> Box {
- box MacItems { items: it.collect() } as Box
+ fn make_methods(self: Box) -> Option>> {
+ self.methods
}
-}
-impl MacResult for MacItems {
- fn make_items(self: Box) -> Option>> {
- Some(self.items)
+ fn make_stmt(self: Box) -> Option> {
+ match self.stmt {
+ None => make_stmt_default!(self),
+ s => s,
+ }
+ }
+
+ fn make_pat(self: Box) -> Option> {
+ if let Some(p) = self.pat {
+ return Some(p);
+ }
+ if let Some(e) = self.expr {
+ if let ast::ExprLit(_) = e.node {
+ return Some(P(ast::Pat {
+ id: ast::DUMMY_NODE_ID,
+ span: e.span,
+ node: ast::PatLit(e),
+ }));
+ }
+ }
+ None
}
}
diff --git a/src/libsyntax/ext/cfg.rs b/src/libsyntax/ext/cfg.rs
index 7216602071b5c..6a2209bf0aee2 100644
--- a/src/libsyntax/ext/cfg.rs
+++ b/src/libsyntax/ext/cfg.rs
@@ -35,5 +35,5 @@ pub fn expand_cfg<'cx>(cx: &mut ExtCtxt,
}
let matches_cfg = attr::cfg_matches(&cx.parse_sess.span_diagnostic, &cx.cfg, &*cfg);
- MacExpr::new(cx.expr_bool(sp, matches_cfg))
+ MacEager::expr(cx.expr_bool(sp, matches_cfg))
}
diff --git a/src/libsyntax/ext/concat.rs b/src/libsyntax/ext/concat.rs
index 84f786e9780f0..754c73a9d7838 100644
--- a/src/libsyntax/ext/concat.rs
+++ b/src/libsyntax/ext/concat.rs
@@ -60,7 +60,7 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt,
}
}
}
- base::MacExpr::new(cx.expr_str(
+ base::MacEager::expr(cx.expr_str(
sp,
token::intern_and_get_ident(&accumulator[..])))
}
diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs
index 2303eb9645b64..e350ce6101737 100644
--- a/src/libsyntax/ext/concat_idents.rs
+++ b/src/libsyntax/ext/concat_idents.rs
@@ -67,5 +67,5 @@ pub fn expand_syntax_ext<'cx>(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]
),
span: sp,
});
- MacExpr::new(e)
+ MacEager::expr(e)
}
diff --git a/src/libsyntax/ext/env.rs b/src/libsyntax/ext/env.rs
index 93f8ee5042bb1..f72303985e78c 100644
--- a/src/libsyntax/ext/env.rs
+++ b/src/libsyntax/ext/env.rs
@@ -59,7 +59,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenT
&s[..]))))
}
};
- MacExpr::new(e)
+ MacEager::expr(e)
}
pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
@@ -108,5 +108,5 @@ pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
}
Ok(s) => cx.expr_str(sp, token::intern_and_get_ident(&s))
};
- MacExpr::new(e)
+ MacEager::expr(e)
}
diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs
index 91262556abd70..0eaca9af4f08d 100644
--- a/src/libsyntax/ext/format.rs
+++ b/src/libsyntax/ext/format.rs
@@ -633,7 +633,7 @@ pub fn expand_format_args<'cx>(ecx: &'cx mut ExtCtxt, sp: Span,
match parse_args(ecx, sp, tts) {
Some((efmt, args, order, names)) => {
- MacExpr::new(expand_preparsed_format_args(ecx, sp, efmt,
+ MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt,
args, order, names))
}
None => DummyResult::expr(sp)
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index 554529b5cb23c..544fb15dcde7b 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -402,7 +402,7 @@ pub fn expand_quote_tokens<'cx>(cx: &'cx mut ExtCtxt,
-> Box {
let (cx_expr, expr) = expand_tts(cx, sp, tts);
let expanded = expand_wrapper(cx, sp, cx_expr, expr);
- base::MacExpr::new(expanded)
+ base::MacEager::expr(expanded)
}
pub fn expand_quote_expr<'cx>(cx: &'cx mut ExtCtxt,
@@ -410,7 +410,7 @@ pub fn expand_quote_expr<'cx>(cx: &'cx mut ExtCtxt,
tts: &[ast::TokenTree])
-> Box {
let expanded = expand_parse_call(cx, sp, "parse_expr", Vec::new(), tts);
- base::MacExpr::new(expanded)
+ base::MacEager::expr(expanded)
}
pub fn expand_quote_item<'cx>(cx: &mut ExtCtxt,
@@ -419,7 +419,7 @@ pub fn expand_quote_item<'cx>(cx: &mut ExtCtxt,
-> Box {
let expanded = expand_parse_call(cx, sp, "parse_item_with_outer_attributes",
vec!(), tts);
- base::MacExpr::new(expanded)
+ base::MacEager::expr(expanded)
}
pub fn expand_quote_pat<'cx>(cx: &'cx mut ExtCtxt,
@@ -427,7 +427,7 @@ pub fn expand_quote_pat<'cx>(cx: &'cx mut ExtCtxt,
tts: &[ast::TokenTree])
-> Box {
let expanded = expand_parse_call(cx, sp, "parse_pat", vec!(), tts);
- base::MacExpr::new(expanded)
+ base::MacEager::expr(expanded)
}
pub fn expand_quote_arm(cx: &mut ExtCtxt,
@@ -435,7 +435,7 @@ pub fn expand_quote_arm(cx: &mut ExtCtxt,
tts: &[ast::TokenTree])
-> Box {
let expanded = expand_parse_call(cx, sp, "parse_arm", vec!(), tts);
- base::MacExpr::new(expanded)
+ base::MacEager::expr(expanded)
}
pub fn expand_quote_ty(cx: &mut ExtCtxt,
@@ -443,7 +443,7 @@ pub fn expand_quote_ty(cx: &mut ExtCtxt,
tts: &[ast::TokenTree])
-> Box {
let expanded = expand_parse_call(cx, sp, "parse_ty", vec!(), tts);
- base::MacExpr::new(expanded)
+ base::MacEager::expr(expanded)
}
pub fn expand_quote_method(cx: &mut ExtCtxt,
@@ -452,7 +452,7 @@ pub fn expand_quote_method(cx: &mut ExtCtxt,
-> Box {
let expanded = expand_parse_call(cx, sp, "parse_method_with_outer_attributes",
vec!(), tts);
- base::MacExpr::new(expanded)
+ base::MacEager::expr(expanded)
}
pub fn expand_quote_stmt(cx: &mut ExtCtxt,
@@ -462,7 +462,7 @@ pub fn expand_quote_stmt(cx: &mut ExtCtxt,
let e_attrs = cx.expr_vec_ng(sp);
let expanded = expand_parse_call(cx, sp, "parse_stmt",
vec!(e_attrs), tts);
- base::MacExpr::new(expanded)
+ base::MacEager::expr(expanded)
}
fn ids_ext(strs: Vec ) -> Vec {
diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs
index af43f5a150190..ba3743cdb335b 100644
--- a/src/libsyntax/ext/source_util.rs
+++ b/src/libsyntax/ext/source_util.rs
@@ -35,7 +35,7 @@ pub fn expand_line(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
let topmost = cx.original_span_in_file();
let loc = cx.codemap().lookup_char_pos(topmost.lo);
- base::MacExpr::new(cx.expr_u32(topmost, loc.line as u32))
+ base::MacEager::expr(cx.expr_u32(topmost, loc.line as u32))
}
/* column!(): expands to the current column number */
@@ -46,7 +46,7 @@ pub fn expand_column(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
let topmost = cx.original_span_in_file();
let loc = cx.codemap().lookup_char_pos(topmost.lo);
- base::MacExpr::new(cx.expr_u32(topmost, loc.col.to_usize() as u32))
+ base::MacEager::expr(cx.expr_u32(topmost, loc.col.to_usize() as u32))
}
/// file!(): expands to the current filename */
@@ -59,13 +59,13 @@ pub fn expand_file(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
let topmost = cx.original_span_in_file();
let loc = cx.codemap().lookup_char_pos(topmost.lo);
let filename = token::intern_and_get_ident(&loc.file.name);
- base::MacExpr::new(cx.expr_str(topmost, filename))
+ base::MacEager::expr(cx.expr_str(topmost, filename))
}
pub fn expand_stringify(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
-> Box {
let s = pprust::tts_to_string(tts);
- base::MacExpr::new(cx.expr_str(sp,
+ base::MacEager::expr(cx.expr_str(sp,
token::intern_and_get_ident(&s[..])))
}
@@ -77,7 +77,7 @@ pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
.map(|x| token::get_ident(*x).to_string())
.collect::>()
.connect("::");
- base::MacExpr::new(cx.expr_str(
+ base::MacEager::expr(cx.expr_str(
sp,
token::intern_and_get_ident(&string[..])))
}
@@ -155,7 +155,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
let interned = token::intern_and_get_ident(&src[..]);
cx.codemap().new_filemap(filename, src);
- base::MacExpr::new(cx.expr_str(sp, interned))
+ base::MacEager::expr(cx.expr_str(sp, interned))
}
Err(_) => {
cx.span_err(sp,
@@ -181,7 +181,7 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
}
Ok(bytes) => {
let bytes = bytes.iter().cloned().collect();
- base::MacExpr::new(cx.expr_lit(sp, ast::LitBinary(Rc::new(bytes))))
+ base::MacEager::expr(cx.expr_lit(sp, ast::LitBinary(Rc::new(bytes))))
}
}
}
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 3a7fa54edbdd7..7acbd10ef03d8 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -27,7 +27,6 @@
#![feature(box_syntax)]
#![feature(collections)]
#![feature(core)]
-#![feature(env)]
#![feature(int_uint)]
#![feature(old_io)]
#![feature(libc)]
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index f171e8279f49c..9de7b0ede78a7 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1163,7 +1163,6 @@ impl<'a> Parser<'a> {
{
self.bump();
self.bump();
- return;
} else if
self.eat(&token::Colon)
{
diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs
index 823d2879236d1..756d67b5db1e1 100644
--- a/src/libterm/lib.rs
+++ b/src/libterm/lib.rs
@@ -59,7 +59,6 @@
#![feature(staged_api)]
#![feature(unicode)]
#![feature(std_misc)]
-#![feature(env)]
#![feature(os)]
#![cfg_attr(windows, feature(libc))]
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 7c7f1fd478aa9..a144904903e58 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -36,7 +36,6 @@
#![feature(box_syntax)]
#![feature(collections)]
#![feature(core)]
-#![feature(env)]
#![feature(int_uint)]
#![feature(old_io)]
#![feature(old_path)]
diff --git a/src/test/auxiliary/issue_16723_multiple_items_syntax_ext.rs b/src/test/auxiliary/issue_16723_multiple_items_syntax_ext.rs
index bb57b4a98bb70..f5a9063e1def5 100644
--- a/src/test/auxiliary/issue_16723_multiple_items_syntax_ext.rs
+++ b/src/test/auxiliary/issue_16723_multiple_items_syntax_ext.rs
@@ -19,7 +19,8 @@ extern crate rustc;
use syntax::ast;
use syntax::codemap;
-use syntax::ext::base::{ExtCtxt, MacResult, MacItems};
+use syntax::ext::base::{ExtCtxt, MacResult, MacEager};
+use syntax::util::small_vector::SmallVector;
use rustc::plugin::Registry;
#[plugin_registrar]
@@ -28,8 +29,8 @@ pub fn plugin_registrar(reg: &mut Registry) {
}
fn expand(cx: &mut ExtCtxt, _: codemap::Span, _: &[ast::TokenTree]) -> Box {
- MacItems::new(vec![
+ MacEager::items(SmallVector::many(vec![
quote_item!(cx, struct Struct1;).unwrap(),
quote_item!(cx, struct Struct2;).unwrap()
- ].into_iter())
+ ]))
}
diff --git a/src/test/auxiliary/macro_crate_test.rs b/src/test/auxiliary/macro_crate_test.rs
index d545a42ae1927..01bfbd3dbceb6 100644
--- a/src/test/auxiliary/macro_crate_test.rs
+++ b/src/test/auxiliary/macro_crate_test.rs
@@ -47,7 +47,7 @@ fn expand_make_a_1(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
if !tts.is_empty() {
cx.span_fatal(sp, "make_a_1 takes no arguments");
}
- MacExpr::new(quote_expr!(cx, 1))
+ MacEager::expr(quote_expr!(cx, 1))
}
// See Issue #15750
@@ -57,7 +57,7 @@ fn expand_identity(cx: &mut ExtCtxt, _span: Span, tts: &[TokenTree])
let mut parser = parse::new_parser_from_tts(cx.parse_sess(),
cx.cfg(), tts.to_vec());
let expr = parser.parse_expr();
- MacExpr::new(quote_expr!(&mut *cx, $expr))
+ MacEager::expr(quote_expr!(&mut *cx, $expr))
}
fn expand_into_foo(cx: &mut ExtCtxt, sp: Span, attr: &MetaItem, it: P- )
@@ -114,7 +114,7 @@ fn expand_forged_ident(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) -> Box>().connect(", ");
let interned = token::intern_and_get_ident(&args[..]);
- MacExpr::new(ecx.expr_str(sp, interned))
+ MacEager::expr(ecx.expr_str(sp, interned))
}
}
diff --git a/src/test/auxiliary/roman_numerals.rs b/src/test/auxiliary/roman_numerals.rs
index e05aa16ba5fbb..e5c4211110558 100644
--- a/src/test/auxiliary/roman_numerals.rs
+++ b/src/test/auxiliary/roman_numerals.rs
@@ -19,7 +19,7 @@ extern crate rustc;
use syntax::codemap::Span;
use syntax::parse::token;
use syntax::ast::{TokenTree, TtToken};
-use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacExpr};
+use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
use syntax::ext::build::AstBuilder; // trait for expr_usize
use rustc::plugin::Registry;
@@ -61,7 +61,7 @@ fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
}
}
- MacExpr::new(cx.expr_usize(sp, total))
+ MacEager::expr(cx.expr_usize(sp, total))
}
#[plugin_registrar]
diff --git a/src/test/auxiliary/syntax_extension_with_dll_deps_2.rs b/src/test/auxiliary/syntax_extension_with_dll_deps_2.rs
index 7a24dd76f32c8..07f3b863af8a1 100644
--- a/src/test/auxiliary/syntax_extension_with_dll_deps_2.rs
+++ b/src/test/auxiliary/syntax_extension_with_dll_deps_2.rs
@@ -30,5 +30,5 @@ pub fn plugin_registrar(reg: &mut Registry) {
fn expand_foo(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
-> Box {
let answer = other::the_answer();
- MacExpr::new(quote_expr!(cx, $answer))
+ MacEager::expr(quote_expr!(cx, $answer))
}
diff --git a/src/test/parse-fail/obsolete-closure-kind.rs b/src/test/parse-fail/obsolete-closure-kind.rs
new file mode 100644
index 0000000000000..89134e806a75c
--- /dev/null
+++ b/src/test/parse-fail/obsolete-closure-kind.rs
@@ -0,0 +1,18 @@
+// Copyright 2015 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that we generate obsolete syntax errors around usages of closure kinds: `|:|`, `|&:|` and
+// `|&mut:|`.
+
+fn main() {
+ let a = |:| {}; //~ ERROR obsolete syntax: `:`, `&mut:`, or `&:`
+ let a = |&:| {}; //~ ERROR obsolete syntax: `:`, `&mut:`, or `&:`
+ let a = |&mut:| {}; //~ ERROR obsolete syntax: `:`, `&mut:`, or `&:`
+}