about summary refs log tree commit diff
diff options
context:
space:
mode:
authorKeegan McAllister <kmcallister@mozilla.com>2014-09-05 19:50:05 -0700
committerKeegan McAllister <kmcallister@mozilla.com>2014-09-08 11:30:55 -0700
commit2b3619412fab979f2599227ef387c91d7c1ee28a (patch)
treed2a763ee6194a701a4f345a69137ab386b3a7543
parent6f34760e4173dda94162502153fe4c5a2a96fc9d (diff)
downloadrust-2b3619412fab979f2599227ef387c91d7c1ee28a.tar.gz
rust-2b3619412fab979f2599227ef387c91d7c1ee28a.zip
quote: Explicitly borrow the ExtCtxt
Fixes #16992.
-rw-r--r--src/librustc/front/test.rs9
-rw-r--r--src/librustc/middle/astencode.rs8
-rw-r--r--src/libsyntax/ext/quote.rs4
-rw-r--r--src/test/run-pass-fulldeps/issue-16992.rs25
4 files changed, 36 insertions, 10 deletions
diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs
index 13f6243fb7b..63e93d266c7 100644
--- a/src/librustc/front/test.rs
+++ b/src/librustc/front/test.rs
@@ -96,7 +96,7 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
 
         // Add a special __test module to the crate that will contain code
         // generated for the test harness
-        let (mod_, reexport) = mk_test_module(&self.cx, &self.cx.reexport_test_harness_main);
+        let (mod_, reexport) = mk_test_module(&mut self.cx);
         folded.module.items.push(mod_);
         match reexport {
             Some(re) => folded.module.view_items.push(re),
@@ -378,8 +378,7 @@ fn mk_std(cx: &TestCtxt) -> ast::ViewItem {
     }
 }
 
-fn mk_test_module(cx: &TestCtxt, reexport_test_harness_main: &Option<InternedString>)
-                  -> (Gc<ast::Item>, Option<ast::ViewItem>) {
+fn mk_test_module(cx: &mut TestCtxt) -> (Gc<ast::Item>, Option<ast::ViewItem>) {
     // Link to test crate
     let view_items = vec!(mk_std(cx));
 
@@ -388,7 +387,7 @@ fn mk_test_module(cx: &TestCtxt, reexport_test_harness_main: &Option<InternedStr
 
     // The synthesized main function which will call the console test runner
     // with our list of tests
-    let mainfn = (quote_item!(&cx.ext_cx,
+    let mainfn = (quote_item!(&mut cx.ext_cx,
         pub fn main() {
             #![main]
             use std::slice::Slice;
@@ -412,7 +411,7 @@ fn mk_test_module(cx: &TestCtxt, reexport_test_harness_main: &Option<InternedStr
         vis: ast::Public,
         span: DUMMY_SP,
     };
-    let reexport = reexport_test_harness_main.as_ref().map(|s| {
+    let reexport = cx.reexport_test_harness_main.as_ref().map(|s| {
         // building `use <ident> = __test::main`
         let reexport_ident = token::str_to_ident(s.get());
 
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index ee964c729fc..e60d8bfdb9d 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -1951,7 +1951,7 @@ fn roundtrip(in_item: Option<Gc<ast::Item>>) {
 #[test]
 fn test_basic() {
     let cx = mk_ctxt();
-    roundtrip(quote_item!(cx,
+    roundtrip(quote_item!(&cx,
         fn foo() {}
     ));
 }
@@ -1959,7 +1959,7 @@ fn test_basic() {
 #[test]
 fn test_smalltalk() {
     let cx = mk_ctxt();
-    roundtrip(quote_item!(cx,
+    roundtrip(quote_item!(&cx,
         fn foo() -> int { 3 + 4 } // first smalltalk program ever executed.
     ));
 }
@@ -1968,7 +1968,7 @@ fn test_smalltalk() {
 #[test]
 fn test_more() {
     let cx = mk_ctxt();
-    roundtrip(quote_item!(cx,
+    roundtrip(quote_item!(&cx,
         fn foo(x: uint, y: uint) -> uint {
             let z = x + y;
             return z;
@@ -1987,7 +1987,7 @@ fn test_simplification() {
     ).unwrap();
     let item_in = e::IIItemRef(&*item);
     let item_out = simplify_ast(item_in);
-    let item_exp = ast::IIItem(quote_item!(cx,
+    let item_exp = ast::IIItem(quote_item!(&cx,
         fn new_int_alist<B>() -> alist<int, B> {
             return alist {eq_fn: eq_int, data: Vec::new()};
         }
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index 0c41db7ecd6..808e671f868 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -766,7 +766,9 @@ fn expand_wrapper(cx: &ExtCtxt,
         cx.view_use_glob(sp, ast::Inherited, ids_ext(path))
     }).collect();
 
-    let stmt_let_ext_cx = cx.stmt_let(sp, false, id_ext("ext_cx"), cx_expr);
+    // Explicitly borrow to avoid moving from the invoker (#16992)
+    let cx_expr_borrow = cx.expr_addr_of(sp, cx.expr_deref(sp, cx_expr));
+    let stmt_let_ext_cx = cx.stmt_let(sp, false, id_ext("ext_cx"), cx_expr_borrow);
 
     cx.expr_block(cx.block_all(sp, uses, vec!(stmt_let_ext_cx), Some(expr)))
 }
diff --git a/src/test/run-pass-fulldeps/issue-16992.rs b/src/test/run-pass-fulldeps/issue-16992.rs
new file mode 100644
index 00000000000..71fab67b819
--- /dev/null
+++ b/src/test/run-pass-fulldeps/issue-16992.rs
@@ -0,0 +1,25 @@
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-pretty
+
+#![feature(quote)]
+
+extern crate syntax;
+
+use syntax::ext::base::ExtCtxt;
+
+#[allow(dead_code)]
+fn foobar(cx: &mut ExtCtxt) {
+    quote_expr!(cx, 1i);
+    quote_expr!(cx, 2i);
+}
+
+fn main() { }