diff --git a/src/test/run-pass/traits-conditional-model-fn.rs b/src/test/run-pass/traits-conditional-model-fn.rs new file mode 100644 index 00000000000..11e144e7dfe --- /dev/null +++ b/src/test/run-pass/traits-conditional-model-fn.rs @@ -0,0 +1,101 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// A model for how the `Fn` traits could work. You can implement at +// 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(this: &G, arg: int) { + this.go(arg) +} + +trait GoMut { + fn go_mut(&mut self, arg: int); +} + +fn go_mut(this: &mut G, arg: int) { + this.go_mut(arg) +} + +trait GoOnce { + fn go_once(self, arg: int); +} + +fn go_once(this: G, arg: int) { + this.go_once(arg) +} + +impl GoMut for G + where G : Go +{ + fn go_mut(&mut self, arg: int) { + go(&*self, arg) + } +} + +impl GoOnce for G + where G : GoMut +{ + fn go_once(mut self, arg: int) { + go_mut(&mut self, arg) + } +} + +/////////////////////////////////////////////////////////////////////////// + +struct SomeGoableThing { + counter: Rc> +} + +impl Go for SomeGoableThing { + fn go(&self, arg: int) { + self.counter.set(self.counter.get() + arg); + } +} + +/////////////////////////////////////////////////////////////////////////// + +struct SomeGoOnceableThing { + counter: Rc> +} + +impl GoOnce for SomeGoOnceableThing { + fn go_once(self, arg: int) { + self.counter.set(self.counter.get() + arg); + } +} + +/////////////////////////////////////////////////////////////////////////// + +fn main() { + let counter = Rc::new(Cell::new(0)); + let mut x = SomeGoableThing { counter: counter.clone() }; + + go(&x, 10); + assert_eq!(counter.get(), 10); + + go_mut(&mut x, 100); + assert_eq!(counter.get(), 110); + + go_once(x, 1_000); + assert_eq!(counter.get(), 1_110); + + let x = SomeGoOnceableThing { counter: counter.clone() }; + + go_once(x, 10_000); + assert_eq!(counter.get(), 11_110); +}