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);
}
}
--- /dev/null
+// 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)
+ }
+}
--- /dev/null
+// 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() { }
// 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;
///////////////////////////////////////////////////////////////////////////