diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index 132b59c89b203..d3c39284f5582 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -13,7 +13,7 @@ use std::collections::HashMap; use ast; use ast::{Ident, Name, TokenTree}; use codemap::Span; -use ext::base::{ExtCtxt, MacExpr, MacItem, MacResult}; +use ext::base::{ExtCtxt, MacExpr, MacResult, MacItems}; use ext::build::AstBuilder; use parse::token; use ptr::P; @@ -102,7 +102,7 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt, let sym = Ident::new(token::gensym(( "__register_diagnostic_".to_string() + token::get_ident(*code).get() ).as_slice())); - MacItem::new(quote_item!(ecx, mod $sym {}).unwrap()) + MacItems::new(vec![quote_item!(ecx, mod $sym {}).unwrap()].into_iter()) } pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt, @@ -133,7 +133,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt, (descriptions.len(), ecx.expr_vec(span, descriptions)) }) }); - MacItem::new(quote_item!(ecx, + MacItems::new(vec![quote_item!(ecx, pub static $name: [(&'static str, &'static str), ..$count] = $expr; - ).unwrap()) + ).unwrap()].into_iter()) } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 773daa4a4c593..fbbbea541a61c 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -203,25 +203,20 @@ impl MacResult for MacPat { Some(self.p) } } -/// A convenience type for macros that return a single item. -pub struct MacItem { - i: P +/// A type for macros that return multiple items. +pub struct MacItems { + items: SmallVector> } -impl MacItem { - pub fn new(i: P) -> Box { - box MacItem { i: i } as Box + +impl MacItems { + pub fn new>>(mut it: I) -> Box { + box MacItems { items: it.collect() } as Box } } -impl MacResult for MacItem { - fn make_items(self: Box) -> Option>> { - Some(SmallVector::one(self.i)) - } - fn make_stmt(self: Box) -> Option> { - Some(P(codemap::respan( - self.i.span, - ast::StmtDecl( - P(codemap::respan(self.i.span, ast::DeclItem(self.i))), - ast::DUMMY_NODE_ID)))) + +impl MacResult for MacItems { + fn make_items(self: Box) -> Option>> { + Some(self.items) } } diff --git a/src/test/auxiliary/issue_16723_multiple_items_syntax_ext.rs b/src/test/auxiliary/issue_16723_multiple_items_syntax_ext.rs new file mode 100644 index 0000000000000..269afea52c262 --- /dev/null +++ b/src/test/auxiliary/issue_16723_multiple_items_syntax_ext.rs @@ -0,0 +1,33 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +// +// ignore-stage1 +#![feature(plugin_registrar, managed_boxes, quote)] +#![crate_type = "dylib"] + +extern crate syntax; +extern crate rustc; + +use syntax::ast; +use syntax::codemap; +use syntax::ext::base::{ExtCtxt, MacResult, MacItems}; +use rustc::plugin::Registry; + +#[plugin_registrar] +pub fn plugin_registrar(reg: &mut Registry) { + reg.register_macro("multiple_items", expand) +} + +fn expand(cx: &mut ExtCtxt, _: codemap::Span, _: &[ast::TokenTree]) -> Box { + MacItems::new(vec![ + quote_item!(cx, struct Struct1;).unwrap(), + quote_item!(cx, struct Struct2;).unwrap() + ].into_iter()) +} diff --git a/src/test/run-pass-fulldeps/issue_16723_multiple_items_syntax_ext.rs b/src/test/run-pass-fulldeps/issue_16723_multiple_items_syntax_ext.rs new file mode 100644 index 0000000000000..431ae1b13dd24 --- /dev/null +++ b/src/test/run-pass-fulldeps/issue_16723_multiple_items_syntax_ext.rs @@ -0,0 +1,30 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-stage1 +// aux-build:issue_16723_multiple_items_syntax_ext.rs +#![feature(phase)] + +#[phase(plugin)] extern crate issue_16723_multiple_items_syntax_ext; + +multiple_items!() + +impl Struct1 { + fn foo() {} +} +impl Struct2 { + fn foo() {} +} + +fn main() { + Struct1::foo(); + Struct2::foo(); + println!("hallo"); +}