about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSteven Fackler <sfackler@gmail.com>2014-02-11 22:43:23 -0800
committerAlex Crichton <alex@alexcrichton.com>2014-02-13 12:50:24 -0800
commit6b429d07c96c3e7cb3130c070d99651f29bded6c (patch)
tree64b728476c3e9d71f277bb899346cd697958780d
parentcfb87f10ec7d41d0e7f8c68fbb908fc195517d41 (diff)
Stop unloading syntax libraries
Externally loaded libraries are able to do things that cause references
to them to survive past the expansion phase (e.g. creating @-box cycles,
launching a task or storing something in task local data). As such, the
library has to stay loaded for the lifetime of the process.
-rw-r--r--src/libsyntax/ext/base.rs8
-rw-r--r--src/libsyntax/ext/expand.rs10
-rw-r--r--src/test/auxiliary/macro_crate_outlive_expansion_phase.rs35
-rw-r--r--src/test/run-pass-fulldeps/macro-crate-outlive-expansion-phase.rs21
4 files changed, 63 insertions, 11 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index d22a1d697fc..02c3a1b985b 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -20,7 +20,6 @@ use parse::token::{InternedString, intern, str_to_ident};
 use util::small_vector::SmallVector;
 
 use std::hashmap::HashMap;
-use std::unstable::dynamic_lib::DynamicLibrary;
 
 // new-style macro! tt code:
 //
@@ -143,8 +142,6 @@ pub struct BlockInfo {
     macros_escape : bool,
     // what are the pending renames?
     pending_renames : RenameList,
-    // references for crates loaded in this scope
-    macro_crates: ~[DynamicLibrary],
 }
 
 impl BlockInfo {
@@ -152,7 +149,6 @@ impl BlockInfo {
         BlockInfo {
             macros_escape: false,
             pending_renames: ~[],
-            macro_crates: ~[],
         }
     }
 }
@@ -551,10 +547,6 @@ impl SyntaxEnv {
         self.find_escape_frame().map.insert(k, v);
     }
 
-    pub fn insert_macro_crate(&mut self, lib: DynamicLibrary) {
-        self.find_escape_frame().info.macro_crates.push(lib);
-    }
-
     pub fn info<'a>(&'a mut self) -> &'a mut BlockInfo {
         &mut self.chain[self.chain.len()-1].info
     }
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index d146cd4dae3..d79c4cbc96a 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -1,4 +1,4 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -28,6 +28,7 @@ use visit;
 use visit::Visitor;
 use util::small_vector::SmallVector;
 
+use std::cast;
 use std::vec;
 use std::unstable::dynamic_lib::DynamicLibrary;
 use std::os;
@@ -469,9 +470,12 @@ fn load_extern_macros(crate: &ast::ViewItem, fld: &mut MacroExpander) {
             };
             fld.extsbox.insert(name, extension);
         });
-    }
 
-    fld.extsbox.insert_macro_crate(lib);
+        // Intentionally leak the dynamic library. We can't ever unload it
+        // since the library can do things that will outlive the expansion
+        // phase (e.g. make an @-box cycle or launch a task).
+        cast::forget(lib);
+    }
 }
 
 // expand a stmt
diff --git a/src/test/auxiliary/macro_crate_outlive_expansion_phase.rs b/src/test/auxiliary/macro_crate_outlive_expansion_phase.rs
new file mode 100644
index 00000000000..eecbb325630
--- /dev/null
+++ b/src/test/auxiliary/macro_crate_outlive_expansion_phase.rs
@@ -0,0 +1,35 @@
+// 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.
+
+// force-host
+
+#[feature(macro_registrar)];
+
+extern mod syntax;
+
+use std::any::Any;
+use std::local_data;
+use syntax::ast::Name;
+use syntax::ext::base::SyntaxExtension;
+
+struct Foo {
+    foo: int
+}
+
+impl Drop for Foo {
+    fn drop(&mut self) {}
+}
+
+#[macro_registrar]
+pub fn registrar(_: |Name, SyntaxExtension|) {
+    local_data_key!(foo: ~Any);
+    local_data::set(foo, ~Foo { foo: 10 } as ~Any);
+}
+
diff --git a/src/test/run-pass-fulldeps/macro-crate-outlive-expansion-phase.rs b/src/test/run-pass-fulldeps/macro-crate-outlive-expansion-phase.rs
new file mode 100644
index 00000000000..a71cc465e88
--- /dev/null
+++ b/src/test/run-pass-fulldeps/macro-crate-outlive-expansion-phase.rs
@@ -0,0 +1,21 @@
+// 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.
+
+// aux-build:macro_crate_outlive_expansion_phase.rs
+// ignore-stage1
+// ignore-fast
+// ignore-android
+
+#[feature(phase)];
+
+#[phase(syntax)]
+extern mod macro_crate_outlive_expansion_phase;
+
+pub fn main() {}