From eef6b4a37b9b7a1753bb91016c36435ad66309dc Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Fri, 1 May 2015 11:27:36 -0700 Subject: [PATCH 1/3] syntax: Allow pretty printing more interpolated items --- src/libsyntax/print/pprust.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 5a002dd790f..419b3726294 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -287,19 +287,19 @@ pub fn token_to_string(tok: &Token) -> String { token::SpecialVarNt(var) => format!("${}", var.as_str()), token::Interpolated(ref nt) => match *nt { - token::NtExpr(ref e) => expr_to_string(&**e), - token::NtMeta(ref e) => meta_item_to_string(&**e), - token::NtTy(ref e) => ty_to_string(&**e), - token::NtPath(ref e) => path_to_string(&**e), - token::NtItem(..) => "an interpolated item".to_string(), - token::NtBlock(..) => "an interpolated block".to_string(), - token::NtStmt(..) => "an interpolated statement".to_string(), - token::NtPat(..) => "an interpolated pattern".to_string(), - token::NtIdent(..) => "an interpolated identifier".to_string(), - token::NtTT(..) => "an interpolated tt".to_string(), - token::NtArm(..) => "an interpolated arm".to_string(), - token::NtImplItem(..) => "an interpolated impl item".to_string(), - token::NtTraitItem(..) => "an interpolated trait item".to_string(), + token::NtExpr(ref e) => expr_to_string(&**e), + token::NtMeta(ref e) => meta_item_to_string(&**e), + token::NtTy(ref e) => ty_to_string(&**e), + token::NtPath(ref e) => path_to_string(&**e), + token::NtItem(ref e) => item_to_string(&**e), + token::NtBlock(ref e) => block_to_string(&**e), + token::NtStmt(ref e) => stmt_to_string(&**e), + token::NtPat(ref e) => pat_to_string(&**e), + token::NtIdent(ref e) => ident_to_string(&**e), + token::NtTT(ref e) => tt_to_string(&**e), + token::NtArm(ref e) => arm_to_string(&**e), + token::NtImplItem(ref e) => impl_item_to_string(&**e), + token::NtTraitItem(ref e) => trait_item_to_string(&**e), } } } From 7b00658413db724525db72364b7f77b65ef6af1d Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Sat, 2 May 2015 10:55:41 -0700 Subject: [PATCH 2/3] syntax: Add unquoting ast::{Generics,WhereClause} --- src/libsyntax/ext/quote.rs | 12 ++++++++++++ src/libsyntax/fold.rs | 3 +++ src/libsyntax/parse/parser.rs | 4 ++++ src/libsyntax/parse/token.rs | 4 ++++ src/libsyntax/print/pprust.rs | 28 +++++++++++++++------------- 5 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index e100b7705d8..39ddafffaec 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -94,6 +94,18 @@ pub mod rt { } } + impl ToTokens for ast::Generics { + fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { + vec![ast::TtToken(DUMMY_SP, token::Interpolated(token::NtGenerics(self.clone())))] + } + } + + impl ToTokens for ast::WhereClause { + fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { + vec![ast::TtToken(DUMMY_SP, token::Interpolated(token::NtWhereClause(self.clone())))] + } + } + impl ToTokens for P { fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { vec![ast::TtToken(self.span, token::Interpolated(token::NtItem(self.clone())))] diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index adfda988b23..4bf15f509a0 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -689,6 +689,9 @@ pub fn noop_fold_interpolated(nt: token::Nonterminal, fld: &mut T) token::NtTraitItem(arm) => token::NtTraitItem(fld.fold_trait_item(arm) .expect_one("expected fold to produce exactly one item")), + token::NtGenerics(generics) => token::NtGenerics(fld.fold_generics(generics)), + token::NtWhereClause(where_clause) => + token::NtWhereClause(fld.fold_where_clause(where_clause)), } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 541ec16b415..9bf6fa88ba5 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3808,6 +3808,8 @@ impl<'a> Parser<'a> { /// | ( < lifetimes , typaramseq ( , )? > ) /// where typaramseq = ( typaram ) | ( typaram , typaramseq ) pub fn parse_generics(&mut self) -> PResult { + maybe_whole!(self, NtGenerics); + if try!(self.eat(&token::Lt) ){ let lifetime_defs = try!(self.parse_lifetime_defs()); let mut seen_default = false; @@ -3928,6 +3930,8 @@ impl<'a> Parser<'a> { /// where T : Trait + 'b, 'a : 'b /// ``` pub fn parse_where_clause(&mut self) -> PResult { + maybe_whole!(self, NtWhereClause); + let mut where_clause = WhereClause { id: ast::DUMMY_NODE_ID, predicates: Vec::new(), diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 53ed4f351d3..832fec40199 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -385,6 +385,8 @@ pub enum Nonterminal { NtArm(ast::Arm), NtImplItem(P), NtTraitItem(P), + NtGenerics(ast::Generics), + NtWhereClause(ast::WhereClause), } impl fmt::Debug for Nonterminal { @@ -403,6 +405,8 @@ impl fmt::Debug for Nonterminal { NtArm(..) => f.pad("NtArm(..)"), NtImplItem(..) => f.pad("NtImplItem(..)"), NtTraitItem(..) => f.pad("NtTraitItem(..)"), + NtGenerics(..) => f.pad("NtGenerics(..)"), + NtWhereClause(..) => f.pad("NtWhereClause(..)"), } } } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 419b3726294..b71d65a8fb0 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -287,19 +287,21 @@ pub fn token_to_string(tok: &Token) -> String { token::SpecialVarNt(var) => format!("${}", var.as_str()), token::Interpolated(ref nt) => match *nt { - token::NtExpr(ref e) => expr_to_string(&**e), - token::NtMeta(ref e) => meta_item_to_string(&**e), - token::NtTy(ref e) => ty_to_string(&**e), - token::NtPath(ref e) => path_to_string(&**e), - token::NtItem(ref e) => item_to_string(&**e), - token::NtBlock(ref e) => block_to_string(&**e), - token::NtStmt(ref e) => stmt_to_string(&**e), - token::NtPat(ref e) => pat_to_string(&**e), - token::NtIdent(ref e) => ident_to_string(&**e), - token::NtTT(ref e) => tt_to_string(&**e), - token::NtArm(ref e) => arm_to_string(&**e), - token::NtImplItem(ref e) => impl_item_to_string(&**e), - token::NtTraitItem(ref e) => trait_item_to_string(&**e), + token::NtExpr(ref e) => expr_to_string(&**e), + token::NtMeta(ref e) => meta_item_to_string(&**e), + token::NtTy(ref e) => ty_to_string(&**e), + token::NtPath(ref e) => path_to_string(&**e), + token::NtItem(ref e) => item_to_string(&**e), + token::NtBlock(ref e) => block_to_string(&**e), + token::NtStmt(ref e) => stmt_to_string(&**e), + token::NtPat(ref e) => pat_to_string(&**e), + token::NtIdent(ref e, _) => ident_to_string(&**e), + token::NtTT(ref e) => tt_to_string(&**e), + token::NtArm(ref e) => arm_to_string(&*e), + token::NtImplItem(ref e) => impl_item_to_string(&**e), + token::NtTraitItem(ref e) => trait_item_to_string(&**e), + token::NtGenerics(ref e) => generics_to_string(&*e), + token::NtWhereClause(ref e) => where_clause_to_string(&*e), } } } From b62290d421acf39db929f05522c8ce530e031067 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Fri, 15 May 2015 08:07:48 -0700 Subject: [PATCH 3/3] syntax: Unquoting some statements requires trailing semicolons --- src/libsyntax/ext/quote.rs | 14 +++++++++++--- src/test/run-pass-fulldeps/quote-tokens.rs | 6 ++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 39ddafffaec..e0753b2f6f6 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -28,8 +28,7 @@ pub mod rt { use ast; use codemap::Spanned; use ext::base::ExtCtxt; - use parse::token; - use parse; + use parse::{self, token, classify}; use ptr::P; use std::rc::Rc; @@ -126,7 +125,16 @@ pub mod rt { impl ToTokens for P { fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { - vec![ast::TtToken(self.span, token::Interpolated(token::NtStmt(self.clone())))] + let mut tts = vec![ + ast::TtToken(self.span, token::Interpolated(token::NtStmt(self.clone()))) + ]; + + // Some statements require a trailing semicolon. + if classify::stmt_ends_with_semi(&self.node) { + tts.push(ast::TtToken(self.span, token::Semi)); + } + + tts } } diff --git a/src/test/run-pass-fulldeps/quote-tokens.rs b/src/test/run-pass-fulldeps/quote-tokens.rs index 64061eb0932..5182f274255 100644 --- a/src/test/run-pass-fulldeps/quote-tokens.rs +++ b/src/test/run-pass-fulldeps/quote-tokens.rs @@ -43,6 +43,12 @@ fn syntax_extension(cx: &ExtCtxt) { let _n: syntax::ast::Attribute = quote_attr!(cx, #![cfg(foo, bar = "baz")]); let _o: Option> = quote_item!(cx, fn foo() {}); + + let stmts = vec![ + quote_stmt!(cx, let x = 1;).unwrap(), + quote_stmt!(cx, let y = 2;).unwrap(), + ]; + let expr: P = quote_expr!(cx, x + y); } fn main() {