diff --git a/maud/src/lib.rs b/maud/src/lib.rs
index a823fa4..1bd5f66 100644
--- a/maud/src/lib.rs
+++ b/maud/src/lib.rs
@@ -61,6 +61,16 @@ pub mod rt {
         Markup { callback: f }
     }
 
+    /// rustc is a butt and doesn't let us quote macro invocations
+    /// directly. So we factor the `write!` call into a separate
+    /// function and use that instead.
+    ///
+    /// See <https://github.com/rust-lang/rust/issues/16617>
+    #[inline]
+    pub fn write_fmt<T: fmt::String>(w: &mut fmt::Writer, value: T) -> fmt::Result {
+        write!(w, "{}", value)
+    }
+
     struct Escaper<'a, 'b: 'a> {
         inner: &'a mut (fmt::Writer + 'b),
     }
diff --git a/maud_macros/src/render.rs b/maud_macros/src/render.rs
index 2144d64..c0bfeb3 100644
--- a/maud_macros/src/render.rs
+++ b/maud_macros/src/render.rs
@@ -1,6 +1,7 @@
 use std::borrow::IntoCow;
 use syntax::ast::{Expr, Ident, Stmt};
 use syntax::ext::base::ExtCtxt;
+use syntax::ext::build::AstBuilder;
 use syntax::parse::token;
 use syntax::ptr::P;
 
@@ -40,10 +41,17 @@ impl<'cx, 's, 'o> Renderer<'cx, 's, 'o> {
             }))
     }
 
+    /// Push an expression statement, also wrapping it with `try!`.
+    fn push(&mut self, expr: P<Expr>) {
+        let expr = self.cx.stmt_expr(self.cx.expr_try(expr.span, expr));
+        self.stmts.push(expr);
+    }
+
     /// Append a literal pre-escaped string.
     fn write(&mut self, s: &str) {
         let w = self.w;
-        self.stmts.push(quote_stmt!(self.cx, try!($w.write_str($s))));
+        let expr = quote_expr!(self.cx, $w.write_str($s));
+        self.push(expr);
     }
 
     /// Append a literal string, with the specified escaping method.
@@ -58,12 +66,14 @@ impl<'cx, 's, 'o> Renderer<'cx, 's, 'o> {
     /// Append the result of an expression, with the specified escaping method.
     pub fn splice(&mut self, expr: P<Expr>, escape: Escape) {
         let w = self.w;
-        self.stmts.push(match escape {
-            Escape::PassThru => quote_stmt!(self.cx, try!(write!($w, "{}", $expr))),
+        let expr = match escape {
+            Escape::PassThru =>
+                quote_expr!(self.cx, ::maud::rt::write_fmt($w, $expr)),
             Escape::Escape =>
-                quote_stmt!(self.cx,
-                    try!(::maud::rt::escape($w, |w| write!(w, "{}", $expr)))),
-        });
+                quote_expr!(self.cx,
+                    ::maud::rt::escape($w, |w| ::maud::rt::write_fmt(w, $expr))),
+        };
+        self.push(expr);
     }
 
     pub fn element_open_start(&mut self, name: &str) {
diff --git a/maud_macros/tests/tests.rs b/maud_macros/tests/tests.rs
index 2a729e6..2d94c2f 100644
--- a/maud_macros/tests/tests.rs
+++ b/maud_macros/tests/tests.rs
@@ -116,14 +116,21 @@ mod splices {
         assert_eq!(s, "Pinkie Pie");
     }
 
-    // FIXME: See <https://github.com/rust-lang/rust/issues/15962>
-    // for why this is commented out
-    /*
     #[test]
     fn closures() {
         let best_pony = "Pinkie Pie";
         let s = html! { $best_pony }.render();
         assert_eq!(s, "Pinkie Pie");
     }
+
+    // FIXME: See <https://github.com/rust-lang/rust/issues/16617>
+    // for why this is commented out
+    /*
+    #[test]
+    fn nested_macro_invocation() {
+        let best_pony = "Pinkie Pie";
+        let s = html! { $(format!("{}", best_pony)) }.render();
+        assert_eq!(s, "Pinkie Pie");
+    }
     */
 }