From 1c0d5e9c31cdd28c6900466fe1e5884078172e6c Mon Sep 17 00:00:00 2001
From: Chris Wong <lambda.fairy@gmail.com>
Date: Sat, 7 Feb 2015 17:48:09 +1300
Subject: [PATCH] Make the renderer owned instead of borrowed

---
 maud_macros/src/lib.rs    |  2 +-
 maud_macros/src/parse.rs  | 37 +++++++++++++++++++++++--------------
 maud_macros/src/render.rs |  5 +++++
 3 files changed, 29 insertions(+), 15 deletions(-)

diff --git a/maud_macros/src/lib.rs b/maud_macros/src/lib.rs
index 4c5b8f5..cd5b3de 100644
--- a/maud_macros/src/lib.rs
+++ b/maud_macros/src/lib.rs
@@ -1,6 +1,6 @@
 #![crate_type = "dylib"]
 #![feature(plugin_registrar, quote)]
-#![feature(core, rustc_private)]
+#![feature(collections, core, rustc_private)]
 
 extern crate syntax;
 extern crate rustc;
diff --git a/maud_macros/src/parse.rs b/maud_macros/src/parse.rs
index cccfea3..64dfee5 100644
--- a/maud_macros/src/parse.rs
+++ b/maud_macros/src/parse.rs
@@ -1,4 +1,4 @@
-use syntax::ast::{Expr, Lit, TokenTree, TtDelimited, TtToken};
+use syntax::ast::{Expr, Lit, Stmt, TokenTree, TtDelimited, TtToken};
 use syntax::codemap::Span;
 use syntax::ext::base::ExtCtxt;
 use syntax::parse;
@@ -41,24 +41,30 @@ macro_rules! ident {
 }
 
 pub fn parse(cx: &ExtCtxt, input: &[TokenTree], sp: Span) -> P<Expr> {
-    let mut render = Renderer::new(cx);
-    Parser {
+    let mut parser = Parser {
         in_attr: false,
         input: input,
         span: sp,
-        render: &mut render,
-    }.markups();
-    render.into_expr()
+        render: Renderer::new(cx),
+    };
+    parser.markups();
+    parser.into_render().into_expr()
 }
 
-struct Parser<'cx: 'r, 's: 'cx, 'i, 'r> {
+struct Parser<'cx, 's: 'cx, 'i> {
     in_attr: bool,
     input: &'i [TokenTree],
     span: Span,
-    render: &'r mut Renderer<'cx, 's>,
+    render: Renderer<'cx, 's>,
 }
 
-impl<'cx, 's, 'i, 'r> Parser<'cx, 's, 'i, 'r> {
+impl<'cx, 's, 'i> Parser<'cx, 's, 'i> {
+    /// Finalize the `Parser`, returning the `Renderer` underneath.
+    fn into_render(self) -> Renderer<'cx, 's> {
+        let Parser { render, .. } = self;
+        render
+    }
+
     /// Consume `n` items from the input.
     fn shift(&mut self, n: usize) {
         self.input = &self.input[n..];
@@ -109,7 +115,8 @@ impl<'cx, 's, 'i, 'r> Parser<'cx, 's, 'i, 'r> {
             // Block
             [TtDelimited(sp, ref d), ..] if d.delim == token::DelimToken::Brace => {
                 self.shift(1);
-                self.block(sp, &d.tts)
+                let stmts = self.block(sp, &d.tts);
+                self.render.push_stmts(stmts);
             },
             // ???
             _ => {
@@ -210,13 +217,15 @@ impl<'cx, 's, 'i, 'r> Parser<'cx, 's, 'i, 'r> {
         }}
     }
 
-    fn block(&mut self, sp: Span, tts: &[TokenTree]) {
-        Parser {
+    fn block(&mut self, sp: Span, tts: &[TokenTree]) -> Vec<P<Stmt>> {
+        let mut parse = Parser {
             in_attr: self.in_attr,
             input: tts,
             span: sp,
-            render: self.render,
-        }.markups();
+            render: Renderer::new(self.render.cx),
+        };
+        parse.markups();
+        parse.into_render().into_stmts()
     }
 }
 
diff --git a/maud_macros/src/render.rs b/maud_macros/src/render.rs
index 2ecfd9a..dc87d24 100644
--- a/maud_macros/src/render.rs
+++ b/maud_macros/src/render.rs
@@ -54,6 +54,11 @@ impl<'cx, 's> Renderer<'cx, 's> {
         stmts
     }
 
+    /// Append the list of statements to the output.
+    pub fn push_stmts(&mut self, mut stmts: Vec<P<Stmt>>) {
+        self.stmts.append(&mut stmts);
+    }
+
     /// Push an expression statement, also wrapping it with `try!`.
     fn push_try(&mut self, expr: P<Expr>) {
         let stmt = self.cx.stmt_expr(self.cx.expr_try(expr.span, expr));