1
Fork 0

Auto merge of #23359 - erickt:quote, r=pnkfelix

This PR allows the quote macros to unquote trait items, impl items, where clauses, and paths.
This commit is contained in:
bors 2015-03-26 18:43:56 +00:00
commit 53a183f027
3 changed files with 41 additions and 29 deletions

View file

@ -171,10 +171,12 @@ pub mod rt {
} }
} }
impl_to_source! { ast::Path, path_to_string }
impl_to_source! { ast::Ty, ty_to_string } impl_to_source! { ast::Ty, ty_to_string }
impl_to_source! { ast::Block, block_to_string } impl_to_source! { ast::Block, block_to_string }
impl_to_source! { ast::Arg, arg_to_string } impl_to_source! { ast::Arg, arg_to_string }
impl_to_source! { Generics, generics_to_string } impl_to_source! { Generics, generics_to_string }
impl_to_source! { ast::WhereClause, where_clause_to_string }
impl_to_source! { P<ast::Item>, item_to_string } impl_to_source! { P<ast::Item>, item_to_string }
impl_to_source! { P<ast::ImplItem>, impl_item_to_string } impl_to_source! { P<ast::ImplItem>, impl_item_to_string }
impl_to_source! { P<ast::TraitItem>, trait_item_to_string } impl_to_source! { P<ast::TraitItem>, trait_item_to_string }
@ -310,6 +312,7 @@ pub mod rt {
} }
impl_to_tokens! { ast::Ident } impl_to_tokens! { ast::Ident }
impl_to_tokens! { ast::Path }
impl_to_tokens! { P<ast::Item> } impl_to_tokens! { P<ast::Item> }
impl_to_tokens! { P<ast::ImplItem> } impl_to_tokens! { P<ast::ImplItem> }
impl_to_tokens! { P<ast::TraitItem> } impl_to_tokens! { P<ast::TraitItem> }
@ -319,6 +322,7 @@ pub mod rt {
impl_to_tokens! { ast::Ty } impl_to_tokens! { ast::Ty }
impl_to_tokens_lifetime! { &'a [ast::Ty] } impl_to_tokens_lifetime! { &'a [ast::Ty] }
impl_to_tokens! { Generics } impl_to_tokens! { Generics }
impl_to_tokens! { ast::WhereClause }
impl_to_tokens! { P<ast::Stmt> } impl_to_tokens! { P<ast::Stmt> }
impl_to_tokens! { P<ast::Expr> } impl_to_tokens! { P<ast::Expr> }
impl_to_tokens! { ast::Block } impl_to_tokens! { ast::Block }

View file

@ -1126,7 +1126,7 @@ impl<'a> Parser<'a> {
p.parse_arg_general(false) p.parse_arg_general(false)
}); });
p.parse_where_clause(&mut generics); generics.where_clause = p.parse_where_clause();
let sig = ast::MethodSig { let sig = ast::MethodSig {
unsafety: style, unsafety: style,
decl: d, decl: d,
@ -3932,9 +3932,14 @@ impl<'a> Parser<'a> {
/// ``` /// ```
/// where T : Trait<U, V> + 'b, 'a : 'b /// where T : Trait<U, V> + 'b, 'a : 'b
/// ``` /// ```
fn parse_where_clause(&mut self, generics: &mut ast::Generics) { fn parse_where_clause(&mut self) -> ast::WhereClause {
let mut where_clause = WhereClause {
id: ast::DUMMY_NODE_ID,
predicates: Vec::new(),
};
if !self.eat_keyword(keywords::Where) { if !self.eat_keyword(keywords::Where) {
return return where_clause;
} }
let mut parsed_something = false; let mut parsed_something = false;
@ -3957,7 +3962,7 @@ impl<'a> Parser<'a> {
let hi = self.span.hi; let hi = self.span.hi;
let span = mk_sp(lo, hi); let span = mk_sp(lo, hi);
generics.where_clause.predicates.push(ast::WherePredicate::RegionPredicate( where_clause.predicates.push(ast::WherePredicate::RegionPredicate(
ast::WhereRegionPredicate { ast::WhereRegionPredicate {
span: span, span: span,
lifetime: bounded_lifetime, lifetime: bounded_lifetime,
@ -3992,7 +3997,7 @@ impl<'a> Parser<'a> {
at least one bound in it"); at least one bound in it");
} }
generics.where_clause.predicates.push(ast::WherePredicate::BoundPredicate( where_clause.predicates.push(ast::WherePredicate::BoundPredicate(
ast::WhereBoundPredicate { ast::WhereBoundPredicate {
span: span, span: span,
bound_lifetimes: bound_lifetimes, bound_lifetimes: bound_lifetimes,
@ -4005,7 +4010,7 @@ impl<'a> Parser<'a> {
// let ty = self.parse_ty(); // let ty = self.parse_ty();
let hi = self.span.hi; let hi = self.span.hi;
let span = mk_sp(lo, hi); let span = mk_sp(lo, hi);
// generics.where_clause.predicates.push( // where_clause.predicates.push(
// ast::WherePredicate::EqPredicate(ast::WhereEqPredicate { // ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
// id: ast::DUMMY_NODE_ID, // id: ast::DUMMY_NODE_ID,
// span: span, // span: span,
@ -4036,6 +4041,8 @@ impl<'a> Parser<'a> {
"a `where` clause must have at least one predicate \ "a `where` clause must have at least one predicate \
in it"); in it");
} }
where_clause
} }
fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool) fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool)
@ -4354,7 +4361,7 @@ impl<'a> Parser<'a> {
fn parse_item_fn(&mut self, unsafety: Unsafety, abi: abi::Abi) -> ItemInfo { fn parse_item_fn(&mut self, unsafety: Unsafety, abi: abi::Abi) -> ItemInfo {
let (ident, mut generics) = self.parse_fn_header(); let (ident, mut generics) = self.parse_fn_header();
let decl = self.parse_fn_decl(false); let decl = self.parse_fn_decl(false);
self.parse_where_clause(&mut generics); generics.where_clause = self.parse_where_clause();
let (inner_attrs, body) = self.parse_inner_attrs_and_block(); let (inner_attrs, body) = self.parse_inner_attrs_and_block();
(ident, ItemFn(decl, unsafety, abi, generics, body), Some(inner_attrs)) (ident, ItemFn(decl, unsafety, abi, generics, body), Some(inner_attrs))
} }
@ -4439,7 +4446,7 @@ impl<'a> Parser<'a> {
let (explicit_self, decl) = self.parse_fn_decl_with_self(|p| { let (explicit_self, decl) = self.parse_fn_decl_with_self(|p| {
p.parse_arg() p.parse_arg()
}); });
self.parse_where_clause(&mut generics); generics.where_clause = self.parse_where_clause();
let (inner_attrs, body) = self.parse_inner_attrs_and_block(); let (inner_attrs, body) = self.parse_inner_attrs_and_block();
(ident, inner_attrs, MethodImplItem(ast::MethodSig { (ident, inner_attrs, MethodImplItem(ast::MethodSig {
generics: generics, generics: generics,
@ -4460,7 +4467,7 @@ impl<'a> Parser<'a> {
// Parse supertrait bounds. // Parse supertrait bounds.
let bounds = self.parse_colon_then_ty_param_bounds(BoundParsingMode::Bare); let bounds = self.parse_colon_then_ty_param_bounds(BoundParsingMode::Bare);
self.parse_where_clause(&mut tps); tps.where_clause = self.parse_where_clause();
let meths = self.parse_trait_items(); let meths = self.parse_trait_items();
(ident, ItemTrait(unsafety, tps, bounds, meths), None) (ident, ItemTrait(unsafety, tps, bounds, meths), None)
@ -4531,7 +4538,7 @@ impl<'a> Parser<'a> {
if opt_trait.is_some() { if opt_trait.is_some() {
ty = self.parse_ty_sum(); ty = self.parse_ty_sum();
} }
self.parse_where_clause(&mut generics); generics.where_clause = self.parse_where_clause();
self.expect(&token::OpenDelim(token::Brace)); self.expect(&token::OpenDelim(token::Brace));
let attrs = self.parse_inner_attributes(); let attrs = self.parse_inner_attributes();
@ -4603,7 +4610,7 @@ impl<'a> Parser<'a> {
// struct. // struct.
let (fields, ctor_id) = if self.token.is_keyword(keywords::Where) { let (fields, ctor_id) = if self.token.is_keyword(keywords::Where) {
self.parse_where_clause(&mut generics); generics.where_clause = self.parse_where_clause();
if self.eat(&token::Semi) { if self.eat(&token::Semi) {
// If we see a: `struct Foo<T> where T: Copy;` style decl. // If we see a: `struct Foo<T> where T: Copy;` style decl.
(Vec::new(), Some(ast::DUMMY_NODE_ID)) (Vec::new(), Some(ast::DUMMY_NODE_ID))
@ -4684,12 +4691,12 @@ impl<'a> Parser<'a> {
token::get_ident(class_name.clone()))); token::get_ident(class_name.clone())));
} }
self.parse_where_clause(generics); generics.where_clause = self.parse_where_clause();
self.expect(&token::Semi); self.expect(&token::Semi);
fields fields
// This is the case where we just see struct Foo<T> where T: Copy; // This is the case where we just see struct Foo<T> where T: Copy;
} else if self.token.is_keyword(keywords::Where) { } else if self.token.is_keyword(keywords::Where) {
self.parse_where_clause(generics); generics.where_clause = self.parse_where_clause();
self.expect(&token::Semi); self.expect(&token::Semi);
Vec::new() Vec::new()
// This case is where we see: `struct Foo<T>;` // This case is where we see: `struct Foo<T>;`
@ -4937,7 +4944,7 @@ impl<'a> Parser<'a> {
let (ident, mut generics) = self.parse_fn_header(); let (ident, mut generics) = self.parse_fn_header();
let decl = self.parse_fn_decl(true); let decl = self.parse_fn_decl(true);
self.parse_where_clause(&mut generics); generics.where_clause = self.parse_where_clause();
let hi = self.span.hi; let hi = self.span.hi;
self.expect(&token::Semi); self.expect(&token::Semi);
P(ast::ForeignItem { P(ast::ForeignItem {
@ -5074,7 +5081,7 @@ impl<'a> Parser<'a> {
fn parse_item_type(&mut self) -> ItemInfo { fn parse_item_type(&mut self) -> ItemInfo {
let ident = self.parse_ident(); let ident = self.parse_ident();
let mut tps = self.parse_generics(); let mut tps = self.parse_generics();
self.parse_where_clause(&mut tps); tps.where_clause = self.parse_where_clause();
self.expect(&token::Eq); self.expect(&token::Eq);
let ty = self.parse_ty_sum(); let ty = self.parse_ty_sum();
self.expect(&token::Semi); self.expect(&token::Semi);
@ -5174,7 +5181,7 @@ impl<'a> Parser<'a> {
fn parse_item_enum(&mut self) -> ItemInfo { fn parse_item_enum(&mut self) -> ItemInfo {
let id = self.parse_ident(); let id = self.parse_ident();
let mut generics = self.parse_generics(); let mut generics = self.parse_generics();
self.parse_where_clause(&mut generics); generics.where_clause = self.parse_where_clause();
self.expect(&token::OpenDelim(token::Brace)); self.expect(&token::OpenDelim(token::Brace));
let enum_definition = self.parse_enum_def(&generics); let enum_definition = self.parse_enum_def(&generics);

View file

@ -367,6 +367,10 @@ pub fn generics_to_string(generics: &ast::Generics) -> String {
$to_string(|s| s.print_generics(generics)) $to_string(|s| s.print_generics(generics))
} }
pub fn where_clause_to_string(i: &ast::WhereClause) -> String {
$to_string(|s| s.print_where_clause(i))
}
pub fn fn_block_to_string(p: &ast::FnDecl) -> String { pub fn fn_block_to_string(p: &ast::FnDecl) -> String {
$to_string(|s| s.print_fn_block_args(p)) $to_string(|s| s.print_fn_block_args(p))
} }
@ -917,7 +921,7 @@ impl<'a> State<'a> {
try!(space(&mut self.s)); try!(space(&mut self.s));
try!(self.word_space("=")); try!(self.word_space("="));
try!(self.print_type(&**ty)); try!(self.print_type(&**ty));
try!(self.print_where_clause(params)); try!(self.print_where_clause(&params.where_clause));
try!(word(&mut self.s, ";")); try!(word(&mut self.s, ";"));
try!(self.end()); // end the outer ibox try!(self.end()); // end the outer ibox
} }
@ -980,7 +984,7 @@ impl<'a> State<'a> {
} }
try!(self.print_type(&**ty)); try!(self.print_type(&**ty));
try!(self.print_where_clause(generics)); try!(self.print_where_clause(&generics.where_clause));
try!(space(&mut self.s)); try!(space(&mut self.s));
try!(self.bopen()); try!(self.bopen());
@ -1008,7 +1012,7 @@ impl<'a> State<'a> {
} }
} }
try!(self.print_bounds(":", &real_bounds[..])); try!(self.print_bounds(":", &real_bounds[..]));
try!(self.print_where_clause(generics)); try!(self.print_where_clause(&generics.where_clause));
try!(word(&mut self.s, " ")); try!(word(&mut self.s, " "));
try!(self.bopen()); try!(self.bopen());
for trait_item in trait_items { for trait_item in trait_items {
@ -1066,7 +1070,7 @@ impl<'a> State<'a> {
try!(self.head(&visibility_qualified(visibility, "enum"))); try!(self.head(&visibility_qualified(visibility, "enum")));
try!(self.print_ident(ident)); try!(self.print_ident(ident));
try!(self.print_generics(generics)); try!(self.print_generics(generics));
try!(self.print_where_clause(generics)); try!(self.print_where_clause(&generics.where_clause));
try!(space(&mut self.s)); try!(space(&mut self.s));
self.print_variants(&enum_definition.variants, span) self.print_variants(&enum_definition.variants, span)
} }
@ -1120,12 +1124,12 @@ impl<'a> State<'a> {
)); ));
try!(self.pclose()); try!(self.pclose());
} }
try!(self.print_where_clause(generics)); try!(self.print_where_clause(&generics.where_clause));
try!(word(&mut self.s, ";")); try!(word(&mut self.s, ";"));
try!(self.end()); try!(self.end());
self.end() // close the outer-box self.end() // close the outer-box
} else { } else {
try!(self.print_where_clause(generics)); try!(self.print_where_clause(&generics.where_clause));
try!(self.nbsp()); try!(self.nbsp());
try!(self.bopen()); try!(self.bopen());
try!(self.hardbreak_if_not_bol()); try!(self.hardbreak_if_not_bol());
@ -2348,7 +2352,7 @@ impl<'a> State<'a> {
} }
try!(self.print_generics(generics)); try!(self.print_generics(generics));
try!(self.print_fn_args_and_ret(decl, opt_explicit_self)); try!(self.print_fn_args_and_ret(decl, opt_explicit_self));
self.print_where_clause(generics) self.print_where_clause(&generics.where_clause)
} }
pub fn print_fn_args(&mut self, decl: &ast::FnDecl, pub fn print_fn_args(&mut self, decl: &ast::FnDecl,
@ -2531,19 +2535,16 @@ impl<'a> State<'a> {
} }
} }
pub fn print_where_clause(&mut self, generics: &ast::Generics) pub fn print_where_clause(&mut self, where_clause: &ast::WhereClause)
-> io::Result<()> { -> io::Result<()> {
if generics.where_clause.predicates.len() == 0 { if where_clause.predicates.len() == 0 {
return Ok(()) return Ok(())
} }
try!(space(&mut self.s)); try!(space(&mut self.s));
try!(self.word_space("where")); try!(self.word_space("where"));
for (i, predicate) in generics.where_clause for (i, predicate) in where_clause.predicates.iter().enumerate() {
.predicates
.iter()
.enumerate() {
if i != 0 { if i != 0 {
try!(self.word_space(",")); try!(self.word_space(","));
} }