about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2014-10-01 07:51:46 -0400
committerNiko Matsakis <niko@alum.mit.edu>2014-10-09 17:19:53 -0400
commit2bb0796ae27b3b1c0563f1779680e63b2ca322c3 (patch)
tree0e7295f76e4a473415fb7e95de5983cbd885c642
parent6340c1a3739de1519f7416ac52263b4234965739 (diff)
downloadrust-2bb0796ae27b3b1c0563f1779680e63b2ca322c3.tar.gz
rust-2bb0796ae27b3b1c0563f1779680e63b2ca322c3.zip
Convert tests to cross-crate, fix a RefCell bug I found in the process.
-rw-r--r--src/librustc/middle/typeck/coherence/overlap.rs12
-rw-r--r--src/test/auxiliary/go_trait.rs51
-rw-r--r--src/test/compile-fail/coherence-blanket-conflicts-with-specific-cross-crate.rs29
-rw-r--r--src/test/run-pass/traits-conditional-model-fn.rs44
4 files changed, 95 insertions, 41 deletions
diff --git a/src/librustc/middle/typeck/coherence/overlap.rs b/src/librustc/middle/typeck/coherence/overlap.rs
index 88e09c30600..ccfa31df826 100644
--- a/src/librustc/middle/typeck/coherence/overlap.rs
+++ b/src/librustc/middle/typeck/coherence/overlap.rs
@@ -35,8 +35,16 @@ struct OverlapChecker<'cx, 'tcx:'cx> {
 impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> {
     fn check_for_overlapping_impls(&self) {
         debug!("check_for_overlapping_impls");
-        let trait_impls = self.tcx.trait_impls.borrow();
-        for trait_def_id in trait_impls.keys() {
+
+        // Collect this into a vector to avoid holding the
+        // refcell-lock during the
+        // check_for_overlapping_impls_of_trait() check, since that
+        // check can populate this table further with impls from other
+        // crates.
+        let trait_def_ids: Vec<ast::DefId> =
+            self.tcx.trait_impls.borrow().keys().map(|&d| d).collect();
+
+        for trait_def_id in trait_def_ids.iter() {
             self.check_for_overlapping_impls_of_trait(*trait_def_id);
         }
     }
diff --git a/src/test/auxiliary/go_trait.rs b/src/test/auxiliary/go_trait.rs
new file mode 100644
index 00000000000..4902766534a
--- /dev/null
+++ b/src/test/auxiliary/go_trait.rs
@@ -0,0 +1,51 @@
+// 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.
+
+// Common code used for tests that model the Fn/FnMut/FnOnce hierarchy.
+
+pub trait Go {
+    fn go(&self, arg: int);
+}
+
+pub fn go<G:Go>(this: &G, arg: int) {
+    this.go(arg)
+}
+
+pub trait GoMut {
+    fn go_mut(&mut self, arg: int);
+}
+
+pub fn go_mut<G:GoMut>(this: &mut G, arg: int) {
+    this.go_mut(arg)
+}
+
+pub trait GoOnce {
+    fn go_once(self, arg: int);
+}
+
+pub fn go_once<G:GoOnce>(this: G, arg: int) {
+    this.go_once(arg)
+}
+
+impl<G> GoMut for G
+    where G : Go
+{
+    fn go_mut(&mut self, arg: int) {
+        go(&*self, arg)
+    }
+}
+
+impl<G> GoOnce for G
+    where G : GoMut
+{
+    fn go_once(mut self, arg: int) {
+        go_mut(&mut self, arg)
+    }
+}
diff --git a/src/test/compile-fail/coherence-blanket-conflicts-with-specific-cross-crate.rs b/src/test/compile-fail/coherence-blanket-conflicts-with-specific-cross-crate.rs
new file mode 100644
index 00000000000..2e163bc11a8
--- /dev/null
+++ b/src/test/compile-fail/coherence-blanket-conflicts-with-specific-cross-crate.rs
@@ -0,0 +1,29 @@
+// 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:go_trait.rs
+
+extern crate go_trait;
+
+use go_trait::{Go,GoMut};
+use std::fmt::Show;
+use std::default::Default;
+
+struct MyThingy;
+
+impl Go for MyThingy {
+    fn go(&self, arg: int) { }
+}
+
+impl GoMut for MyThingy { //~ ERROR conflicting implementations
+    fn go_mut(&mut self, arg: int) { }
+}
+
+fn main() { }
diff --git a/src/test/run-pass/traits-conditional-model-fn.rs b/src/test/run-pass/traits-conditional-model-fn.rs
index 11e144e7dfe..92ba5aad059 100644
--- a/src/test/run-pass/traits-conditional-model-fn.rs
+++ b/src/test/run-pass/traits-conditional-model-fn.rs
@@ -12,48 +12,14 @@
 // most one of `Go`, `GoMut`, or `GoOnce`, and then the others follow
 // automatically.
 
-use std::rc::Rc;
-use std::cell::Cell;
-
-trait Go {
-    fn go(&self, arg: int);
-}
-
-fn go<G:Go>(this: &G, arg: int) {
-    this.go(arg)
-}
+// aux-build:go_trait.rs
 
-trait GoMut {
-    fn go_mut(&mut self, arg: int);
-}
+extern crate go_trait;
 
-fn go_mut<G:GoMut>(this: &mut G, arg: int) {
-    this.go_mut(arg)
-}
-
-trait GoOnce {
-    fn go_once(self, arg: int);
-}
+use go_trait::{Go, GoMut, GoOnce, go, go_mut, go_once};
 
-fn go_once<G:GoOnce>(this: G, arg: int) {
-    this.go_once(arg)
-}
-
-impl<G> GoMut for G
-    where G : Go
-{
-    fn go_mut(&mut self, arg: int) {
-        go(&*self, arg)
-    }
-}
-
-impl<G> GoOnce for G
-    where G : GoMut
-{
-    fn go_once(mut self, arg: int) {
-        go_mut(&mut self, arg)
-    }
-}
+use std::rc::Rc;
+use std::cell::Cell;
 
 ///////////////////////////////////////////////////////////////////////////