about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2015-03-11 10:08:33 -0400
committerNiko Matsakis <niko@alum.mit.edu>2015-03-23 19:57:30 -0400
commit9330bae4bde720dbdf8d379bd5529a1bb7a6f1e9 (patch)
tree969855cd9cb464c2a238151829cfaed3933ff7ed
parent37601131a0ffc49e93b8797020429a980520171c (diff)
downloadrust-9330bae4bde720dbdf8d379bd5529a1bb7a6f1e9.tar.gz
rust-9330bae4bde720dbdf8d379bd5529a1bb7a6f1e9.zip
Fallout from changing fn traits to use inheritance rather than bridge
impls. This is a [breaking-change] (for gated code) in that when you
implement `Fn` (`FnMut`) you must also implement `FnOnce`. This commit
demonstrates how to fix it.
-rw-r--r--src/libcollectionstest/btree/set.rs10
-rw-r--r--src/test/compile-fail/borrowck-overloaded-call.rs18
-rw-r--r--src/test/compile-fail/coerce-unsafe-to-closure.rs3
-rw-r--r--src/test/compile-fail/extern-wrong-value-type.rs2
-rw-r--r--src/test/compile-fail/feature-gate-unboxed-closures-manual-impls.rs13
-rw-r--r--src/test/compile-fail/fn-trait-formatting.rs2
-rw-r--r--src/test/compile-fail/fn-variance-1.rs8
-rw-r--r--src/test/compile-fail/issue-15094.rs7
-rw-r--r--src/test/compile-fail/issue-20225.rs12
-rw-r--r--src/test/compile-fail/overloaded-calls-bad.rs9
-rw-r--r--src/test/compile-fail/overloaded-calls-nontuple.rs6
-rw-r--r--src/test/compile-fail/unboxed-closures-fnmut-as-fn.rs9
-rw-r--r--src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs9
-rw-r--r--src/test/compile-fail/unboxed-closures-unsafe-extern-fn.rs8
-rw-r--r--src/test/compile-fail/unboxed-closures-wrong-abi.rs8
-rw-r--r--src/test/compile-fail/unboxed-closures-wrong-arg-type-extern-fn.rs8
-rw-r--r--src/test/run-pass/issue-13655.rs15
-rw-r--r--src/test/run-pass/issue-14958.rs10
-rw-r--r--src/test/run-pass/issue-14959.rs14
-rw-r--r--src/test/run-pass/issue-16739.rs22
-rw-r--r--src/test/run-pass/issue-19982.rs10
-rw-r--r--src/test/run-pass/overloaded-calls-param-vtables.rs11
-rw-r--r--src/test/run-pass/overloaded-calls-simple.rs18
-rw-r--r--src/test/run-pass/overloaded-calls-zero-args.rs6
-rw-r--r--src/test/run-pass/unboxed-closures-fn-as-fnmut-and-fnonce.rs10
-rw-r--r--src/test/run-pass/unboxed-closures-fnmut-as-fnonce.rs8
-rw-r--r--src/test/run-pass/unboxed-closures-infer-recursive-fn.rs11
-rw-r--r--src/test/run-pass/unboxed-closures-manual-impl.rs8
28 files changed, 216 insertions, 59 deletions
diff --git a/src/libcollectionstest/btree/set.rs b/src/libcollectionstest/btree/set.rs
index 488f0d756d3..234cd6e0fd2 100644
--- a/src/libcollectionstest/btree/set.rs
+++ b/src/libcollectionstest/btree/set.rs
@@ -43,8 +43,6 @@ struct Counter<'a, 'b> {
 }
 
 impl<'a, 'b, 'c> FnMut<(&'c i32,)> for Counter<'a, 'b> {
-    type Output = bool;
-
     extern "rust-call" fn call_mut(&mut self, (&x,): (&'c i32,)) -> bool {
         assert_eq!(x, self.expected[*self.i]);
         *self.i += 1;
@@ -52,6 +50,14 @@ impl<'a, 'b, 'c> FnMut<(&'c i32,)> for Counter<'a, 'b> {
     }
 }
 
+impl<'a, 'b, 'c> FnOnce<(&'c i32,)> for Counter<'a, 'b> {
+    type Output = bool;
+
+    extern "rust-call" fn call_once(mut self, args: (&'c i32,)) -> bool {
+        self.call_mut(args)
+    }
+}
+
 fn check<F>(a: &[i32], b: &[i32], expected: &[i32], f: F) where
     // FIXME Replace Counter with `Box<FnMut(_) -> _>`
     F: FnOnce(&BTreeSet<i32>, &BTreeSet<i32>, Counter) -> bool,
diff --git a/src/test/compile-fail/borrowck-overloaded-call.rs b/src/test/compile-fail/borrowck-overloaded-call.rs
index 673c025e863..93c37524bf5 100644
--- a/src/test/compile-fail/borrowck-overloaded-call.rs
+++ b/src/test/compile-fail/borrowck-overloaded-call.rs
@@ -18,26 +18,36 @@ struct SFn {
 }
 
 impl Fn<(isize,)> for SFn {
-    type Output = isize;
-
     extern "rust-call" fn call(&self, (z,): (isize,)) -> isize {
         self.x * self.y * z
     }
 }
 
+impl FnMut<(isize,)> for SFn {
+    extern "rust-call" fn call_mut(&mut self, args: (isize,)) -> isize { self.call(args) }
+}
+
+impl FnOnce<(isize,)> for SFn {
+    type Output = isize;
+    extern "rust-call" fn call_once(self, args: (isize,)) -> isize { self.call(args) }
+}
+
 struct SFnMut {
     x: isize,
     y: isize,
 }
 
 impl FnMut<(isize,)> for SFnMut {
-    type Output = isize;
-
     extern "rust-call" fn call_mut(&mut self, (z,): (isize,)) -> isize {
         self.x * self.y * z
     }
 }
 
+impl FnOnce<(isize,)> for SFnMut {
+    type Output = isize;
+    extern "rust-call" fn call_once(mut self, args: (isize,)) -> isize { self.call_mut(args) }
+}
+
 struct SFnOnce {
     x: String,
 }
diff --git a/src/test/compile-fail/coerce-unsafe-to-closure.rs b/src/test/compile-fail/coerce-unsafe-to-closure.rs
index fe7635f065c..27b4a04054f 100644
--- a/src/test/compile-fail/coerce-unsafe-to-closure.rs
+++ b/src/test/compile-fail/coerce-unsafe-to-closure.rs
@@ -10,5 +10,6 @@
 
 fn main() {
     let x: Option<&[u8]> = Some("foo").map(std::mem::transmute);
-    //~^ ERROR: is not implemented for the type
+    //~^ ERROR E0277
+    //~| ERROR E0277
 }
diff --git a/src/test/compile-fail/extern-wrong-value-type.rs b/src/test/compile-fail/extern-wrong-value-type.rs
index db3373ea027..d1abed9b262 100644
--- a/src/test/compile-fail/extern-wrong-value-type.rs
+++ b/src/test/compile-fail/extern-wrong-value-type.rs
@@ -18,5 +18,5 @@ fn main() {
     let _x: extern "C" fn() = f; // OK
     is_fn(f);
     //~^ ERROR the trait `core::ops::Fn<()>` is not implemented for the type `extern "C" fn()
-    //~| ERROR the trait `core::ops::Fn<()>` is not implemented for the type `extern "C" fn()
+    //~| ERROR the trait `core::ops::FnOnce<()>` is not implemented for the type `extern "C" fn()
 }
diff --git a/src/test/compile-fail/feature-gate-unboxed-closures-manual-impls.rs b/src/test/compile-fail/feature-gate-unboxed-closures-manual-impls.rs
index e5e5ddadafc..d86c5d211dc 100644
--- a/src/test/compile-fail/feature-gate-unboxed-closures-manual-impls.rs
+++ b/src/test/compile-fail/feature-gate-unboxed-closures-manual-impls.rs
@@ -18,28 +18,21 @@
 struct Foo;
 impl Fn<()> for Foo {
     //~^ ERROR angle-bracket notation is not stable when used with the `Fn` family of traits
-    type Output = ();
-
-    extern "rust-call" fn call(&self, args: ()) -> () {}
+    extern "rust-call" fn call(self, args: ()) -> () {}
 }
 struct Foo1;
-impl Fn() for Foo1 {
+impl FnOnce() for Foo1 {
     //~^ ERROR associated type bindings are not allowed here
-
-    extern "rust-call" fn call(&self, args: ()) -> () {}
+    extern "rust-call" fn call_once(self, args: ()) -> () {}
 }
 struct Bar;
 impl FnMut<()> for Bar {
     //~^ ERROR angle-bracket notation is not stable when used with the `Fn` family of traits
-    type Output = ();
-
     extern "rust-call" fn call_mut(&self, args: ()) -> () {}
 }
 struct Baz;
 impl FnOnce<()> for Baz {
     //~^ ERROR angle-bracket notation is not stable when used with the `Fn` family of traits
-    type Output = ();
-
     extern "rust-call" fn call_once(&self, args: ()) -> () {}
 }
 
diff --git a/src/test/compile-fail/fn-trait-formatting.rs b/src/test/compile-fail/fn-trait-formatting.rs
index 35c55193136..6433255bd4d 100644
--- a/src/test/compile-fail/fn-trait-formatting.rs
+++ b/src/test/compile-fail/fn-trait-formatting.rs
@@ -35,5 +35,5 @@ fn main() {
 
     needs_fn(1);
     //~^ ERROR `core::ops::Fn<(isize,)>`
-    //~| ERROR `core::ops::Fn<(isize,)>`
+    //~| ERROR `core::ops::FnOnce<(isize,)>`
 }
diff --git a/src/test/compile-fail/fn-variance-1.rs b/src/test/compile-fail/fn-variance-1.rs
index 838e65e1d05..8e1e88a92e4 100644
--- a/src/test/compile-fail/fn-variance-1.rs
+++ b/src/test/compile-fail/fn-variance-1.rs
@@ -17,9 +17,13 @@ fn apply<T, F>(t: T, f: F) where F: FnOnce(T) {
 }
 
 fn main() {
-    apply(&3, takes_mut); //~ ERROR (values differ in mutability)
     apply(&3, takes_imm);
+    apply(&3, takes_mut);
+    //~^ ERROR (values differ in mutability)
+    //~| ERROR (values differ in mutability)
 
     apply(&mut 3, takes_mut);
-    apply(&mut 3, takes_imm); //~ ERROR (values differ in mutability)
+    apply(&mut 3, takes_imm);
+    //~^ ERROR (values differ in mutability)
+    //~| ERROR (values differ in mutability)
 }
diff --git a/src/test/compile-fail/issue-15094.rs b/src/test/compile-fail/issue-15094.rs
index 8f79022405e..3853434e128 100644
--- a/src/test/compile-fail/issue-15094.rs
+++ b/src/test/compile-fail/issue-15094.rs
@@ -16,11 +16,10 @@ struct Debuger<T> {
     x: T
 }
 
-impl<T: fmt::Debug> ops::Fn<(),> for Debuger<T> {
+impl<T: fmt::Debug> ops::FnOnce<(),> for Debuger<T> {
     type Output = ();
-
-    fn call(&self, _args: ()) {
-//~^ ERROR `call` has an incompatible type for trait: expected "rust-call" fn, found "Rust" fn
+    fn call_once(self, _args: ()) {
+//~^ ERROR `call_once` has an incompatible type for trait: expected "rust-call" fn, found "Rust" fn
         println!("{:?}", self.x);
     }
 }
diff --git a/src/test/compile-fail/issue-20225.rs b/src/test/compile-fail/issue-20225.rs
index e4bedbbb7e1..fe427e02451 100644
--- a/src/test/compile-fail/issue-20225.rs
+++ b/src/test/compile-fail/issue-20225.rs
@@ -13,9 +13,19 @@
 struct Foo;
 
 impl<'a, T> Fn<(&'a T,)> for Foo {
+  extern "rust-call" fn call(&self, (_,): (T,)) {}
+  //~^ ERROR: has an incompatible type for trait: expected &-ptr
+}
+
+impl<'a, T> FnMut<(&'a T,)> for Foo {
+  extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {}
+  //~^ ERROR: has an incompatible type for trait: expected &-ptr
+}
+
+impl<'a, T> FnOnce<(&'a T,)> for Foo {
   type Output = ();
 
-  extern "rust-call" fn call(&self, (_,): (T,)) {}
+  extern "rust-call" fn call_once(self, (_,): (T,)) {}
   //~^ ERROR: has an incompatible type for trait: expected &-ptr
 }
 
diff --git a/src/test/compile-fail/overloaded-calls-bad.rs b/src/test/compile-fail/overloaded-calls-bad.rs
index 61752e62abd..77ac97bc8b8 100644
--- a/src/test/compile-fail/overloaded-calls-bad.rs
+++ b/src/test/compile-fail/overloaded-calls-bad.rs
@@ -18,13 +18,18 @@ struct S {
 }
 
 impl FnMut<(isize,)> for S {
-    type Output = isize;
-
     extern "rust-call" fn call_mut(&mut self, (z,): (isize,)) -> isize {
         self.x * self.y * z
     }
 }
 
+impl FnOnce<(isize,)> for S {
+    type Output = isize;
+    extern "rust-call" fn call_once(mut self, (z,): (isize,)) -> isize {
+        self.call_mut((z,))
+    }
+}
+
 fn main() {
     let mut s = S {
         x: 3,
diff --git a/src/test/compile-fail/overloaded-calls-nontuple.rs b/src/test/compile-fail/overloaded-calls-nontuple.rs
index c4019fa2209..ea47d676412 100644
--- a/src/test/compile-fail/overloaded-calls-nontuple.rs
+++ b/src/test/compile-fail/overloaded-calls-nontuple.rs
@@ -18,12 +18,16 @@ struct S {
 }
 
 impl FnMut<isize> for S {
-    type Output = isize;
     extern "rust-call" fn call_mut(&mut self, z: isize) -> isize {
         self.x + self.y + z
     }
 }
 
+impl FnOnce<isize> for S {
+    type Output = isize;
+    extern "rust-call" fn call_once(mut self, z: isize) -> isize { self.call_mut(z) }
+}
+
 fn main() {
     let mut s = S {
         x: 1,
diff --git a/src/test/compile-fail/unboxed-closures-fnmut-as-fn.rs b/src/test/compile-fail/unboxed-closures-fnmut-as-fn.rs
index 92e6affa4c2..93498ac7f83 100644
--- a/src/test/compile-fail/unboxed-closures-fnmut-as-fn.rs
+++ b/src/test/compile-fail/unboxed-closures-fnmut-as-fn.rs
@@ -19,13 +19,17 @@ use std::ops::{Fn,FnMut,FnOnce};
 struct S;
 
 impl FnMut<(isize,)> for S {
-    type Output = isize;
-
     extern "rust-call" fn call_mut(&mut self, (x,): (isize,)) -> isize {
         x * x
     }
 }
 
+impl FnOnce<(isize,)> for S {
+    type Output = isize;
+
+    extern "rust-call" fn call_once(mut self, args: (isize,)) -> isize { self.call_mut(args) }
+}
+
 fn call_it<F:Fn(isize)->isize>(f: &F, x: isize) -> isize {
     f.call((x,))
 }
@@ -33,5 +37,4 @@ fn call_it<F:Fn(isize)->isize>(f: &F, x: isize) -> isize {
 fn main() {
     let x = call_it(&S, 22);
     //~^ ERROR not implemented
-    //~| ERROR not implemented
 }
diff --git a/src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs b/src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs
index 713b64b1349..2dcd7a97d89 100644
--- a/src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs
+++ b/src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs
@@ -28,14 +28,19 @@ impl<F,A,R> YCombinator<F,A,R> {
 }
 
 impl<A,R,F : FnMut(&mut FnMut(A) -> R, A) -> R> FnMut<(A,)> for YCombinator<F,A,R> {
-    type Output = R;
-
     extern "rust-call" fn call_mut(&mut self, (arg,): (A,)) -> R {
         (self.func)(self, arg)
             //~^ ERROR cannot borrow `*self` as mutable more than once at a time
     }
 }
 
+impl<A,R,F : FnMut(&mut FnMut(A) -> R, A) -> R> FnOnce<(A,)> for YCombinator<F,A,R> {
+    type Output = R;
+    extern "rust-call" fn call_once(mut self, args: (A,)) -> R {
+        self.call_mut(args)
+    }
+}
+
 fn main() {
     let mut counter = 0;
     let factorial = |recur: &mut FnMut(u32) -> u32, arg: u32| -> u32 {
diff --git a/src/test/compile-fail/unboxed-closures-unsafe-extern-fn.rs b/src/test/compile-fail/unboxed-closures-unsafe-extern-fn.rs
index 23f7ee2b010..dc7c70ba649 100644
--- a/src/test/compile-fail/unboxed-closures-unsafe-extern-fn.rs
+++ b/src/test/compile-fail/unboxed-closures-unsafe-extern-fn.rs
@@ -27,11 +27,15 @@ fn a() {
 }
 
 fn b() {
-    let y = call_it_mut(&mut square, 22); //~ ERROR not implemented
+    let y = call_it_mut(&mut square, 22);
+    //~^ ERROR not implemented
+    //~| ERROR not implemented
 }
 
 fn c() {
-    let z = call_it_once(square, 22); //~ ERROR not implemented
+    let z = call_it_once(square, 22);
+    //~^ ERROR not implemented
+    //~| ERROR not implemented
 }
 
 fn main() { }
diff --git a/src/test/compile-fail/unboxed-closures-wrong-abi.rs b/src/test/compile-fail/unboxed-closures-wrong-abi.rs
index 40655f8a3ce..cdcb435b65a 100644
--- a/src/test/compile-fail/unboxed-closures-wrong-abi.rs
+++ b/src/test/compile-fail/unboxed-closures-wrong-abi.rs
@@ -27,11 +27,15 @@ fn a() {
 }
 
 fn b() {
-    let y = call_it_mut(&mut square, 22); //~ ERROR not implemented
+    let y = call_it_mut(&mut square, 22);
+    //~^ ERROR not implemented
+    //~| ERROR not implemented
 }
 
 fn c() {
-    let z = call_it_once(square, 22); //~ ERROR not implemented
+    let z = call_it_once(square, 22);
+    //~^ ERROR not implemented
+    //~| ERROR not implemented
 }
 
 fn main() { }
diff --git a/src/test/compile-fail/unboxed-closures-wrong-arg-type-extern-fn.rs b/src/test/compile-fail/unboxed-closures-wrong-arg-type-extern-fn.rs
index ebcbdbbc006..150bf36dcc2 100644
--- a/src/test/compile-fail/unboxed-closures-wrong-arg-type-extern-fn.rs
+++ b/src/test/compile-fail/unboxed-closures-wrong-arg-type-extern-fn.rs
@@ -28,11 +28,15 @@ fn a() {
 }
 
 fn b() {
-    let y = call_it_mut(&mut square, 22); //~ ERROR not implemented
+    let y = call_it_mut(&mut square, 22);
+    //~^ ERROR not implemented
+    //~| ERROR not implemented
 }
 
 fn c() {
-    let z = call_it_once(square, 22); //~ ERROR not implemented
+    let z = call_it_once(square, 22);
+    //~^ ERROR not implemented
+    //~| ERROR not implemented
 }
 
 fn main() { }
diff --git a/src/test/run-pass/issue-13655.rs b/src/test/run-pass/issue-13655.rs
index 81a8b29461c..6c0e5edae72 100644
--- a/src/test/run-pass/issue-13655.rs
+++ b/src/test/run-pass/issue-13655.rs
@@ -14,7 +14,6 @@ use std::ops::Fn;
 struct Foo<T>(T);
 
 impl<T: Copy> Fn<()> for Foo<T> {
-    type Output = T;
     extern "rust-call" fn call(&self, _: ()) -> T {
       match *self {
         Foo(t) => t
@@ -22,6 +21,20 @@ impl<T: Copy> Fn<()> for Foo<T> {
     }
 }
 
+impl<T: Copy> FnMut<()> for Foo<T> {
+    extern "rust-call" fn call_mut(&mut self, _: ()) -> T {
+        self.call(())
+    }
+}
+
+impl<T: Copy> FnOnce<()> for Foo<T> {
+    type Output = T;
+
+    extern "rust-call" fn call_once(self, _: ()) -> T {
+        self.call(())
+    }
+}
+
 fn main() {
   let t: u8 = 1;
   println!("{}", Foo(t)());
diff --git a/src/test/run-pass/issue-14958.rs b/src/test/run-pass/issue-14958.rs
index 6335f79be6c..ab5a2f03ece 100644
--- a/src/test/run-pass/issue-14958.rs
+++ b/src/test/run-pass/issue-14958.rs
@@ -15,10 +15,18 @@ trait Foo { fn dummy(&self) { }}
 struct Bar;
 
 impl<'a> std::ops::Fn<(&'a (Foo+'a),)> for Bar {
-    type Output = ();
     extern "rust-call" fn call(&self, _: (&'a Foo,)) {}
 }
 
+impl<'a> std::ops::FnMut<(&'a (Foo+'a),)> for Bar {
+    extern "rust-call" fn call_mut(&mut self, a: (&'a Foo,)) { self.call(a) }
+}
+
+impl<'a> std::ops::FnOnce<(&'a (Foo+'a),)> for Bar {
+    type Output = ();
+    extern "rust-call" fn call_once(self, a: (&'a Foo,)) { self.call(a) }
+}
+
 struct Baz;
 
 impl Foo for Baz {}
diff --git a/src/test/run-pass/issue-14959.rs b/src/test/run-pass/issue-14959.rs
index 53d0f7dae05..91ad7e03623 100644
--- a/src/test/run-pass/issue-14959.rs
+++ b/src/test/run-pass/issue-14959.rs
@@ -34,9 +34,21 @@ impl Alloy {
 }
 
 impl<'b> Fn<(&'b mut (Response+'b),)> for SendFile {
+    extern "rust-call" fn call(&self, (_res,): (&'b mut (Response+'b),)) {}
+}
+
+impl<'b> FnMut<(&'b mut (Response+'b),)> for SendFile {
+    extern "rust-call" fn call_mut(&mut self, (_res,): (&'b mut (Response+'b),)) {
+        self.call((_res,))
+    }
+}
+
+impl<'b> FnOnce<(&'b mut (Response+'b),)> for SendFile {
     type Output = ();
 
-    extern "rust-call" fn call(&self, (_res,): (&'b mut (Response+'b),)) {}
+    extern "rust-call" fn call_once(self, (_res,): (&'b mut (Response+'b),)) {
+        self.call((_res,))
+    }
 }
 
 impl<Rq: Request, Rs: Response> Ingot<Rq, Rs> for HelloWorld {
diff --git a/src/test/run-pass/issue-16739.rs b/src/test/run-pass/issue-16739.rs
index 389baecafd1..fda35d3e7f4 100644
--- a/src/test/run-pass/issue-16739.rs
+++ b/src/test/run-pass/issue-16739.rs
@@ -18,20 +18,36 @@
 struct Foo { foo: u32 }
 
 impl FnMut<()> for Foo {
-    type Output = u32;
     extern "rust-call" fn call_mut(&mut self, _: ()) -> u32 { self.foo }
 }
 
-impl FnMut<(u32,)> for Foo {
+impl FnOnce<()> for Foo {
     type Output = u32;
+    extern "rust-call" fn call_once(mut self, _: ()) -> u32 { self.call_mut(()) }
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+impl FnMut<(u32,)> for Foo {
     extern "rust-call" fn call_mut(&mut self, (x,): (u32,)) -> u32 { self.foo + x }
 }
 
-impl FnMut<(u32,u32)> for Foo {
+impl FnOnce<(u32,)> for Foo {
     type Output = u32;
+    extern "rust-call" fn call_once(mut self, args: (u32,)) -> u32 { self.call_mut(args) }
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+impl FnMut<(u32,u32)> for Foo {
     extern "rust-call" fn call_mut(&mut self, (x, y): (u32, u32)) -> u32 { self.foo + x + y }
 }
 
+impl FnOnce<(u32,u32)> for Foo {
+    type Output = u32;
+    extern "rust-call" fn call_once(mut self, args: (u32,u32)) -> u32 { self.call_mut(args) }
+}
+
 fn main() {
     let mut f = box Foo { foo: 42 } as Box<FnMut() -> u32>;
     assert_eq!(f.call_mut(()), 42);
diff --git a/src/test/run-pass/issue-19982.rs b/src/test/run-pass/issue-19982.rs
index 3082fc27a7d..9a476f563ed 100644
--- a/src/test/run-pass/issue-19982.rs
+++ b/src/test/run-pass/issue-19982.rs
@@ -14,9 +14,17 @@
 struct Foo;
 
 impl<'a> Fn<(&'a (),)> for Foo {
+    extern "rust-call" fn call(&self, (_,): (&(),)) {}
+}
+
+impl<'a> FnMut<(&'a (),)> for Foo {
+    extern "rust-call" fn call_mut(&mut self, (_,): (&(),)) {}
+}
+
+impl<'a> FnOnce<(&'a (),)> for Foo {
     type Output = ();
 
-    extern "rust-call" fn call(&self, (_,): (&(),)) {}
+    extern "rust-call" fn call_once(self, (_,): (&(),)) {}
 }
 
 fn main() {}
diff --git a/src/test/run-pass/overloaded-calls-param-vtables.rs b/src/test/run-pass/overloaded-calls-param-vtables.rs
index 0ac9c97532b..081e1417d5f 100644
--- a/src/test/run-pass/overloaded-calls-param-vtables.rs
+++ b/src/test/run-pass/overloaded-calls-param-vtables.rs
@@ -19,13 +19,20 @@ use std::ops::Add;
 struct G<A>(PhantomData<A>);
 
 impl<'a, A: Add<i32, Output=i32>> Fn<(A,)> for G<A> {
-    type Output = i32;
-
     extern "rust-call" fn call(&self, (arg,): (A,)) -> i32 {
         arg.add(1)
     }
 }
 
+impl<'a, A: Add<i32, Output=i32>> FnMut<(A,)> for G<A> {
+    extern "rust-call" fn call_mut(&mut self, args: (A,)) -> i32 { self.call(args) }
+}
+
+impl<'a, A: Add<i32, Output=i32>> FnOnce<(A,)> for G<A> {
+    type Output = i32;
+    extern "rust-call" fn call_once(self, args: (A,)) -> i32 { self.call(args) }
+}
+
 fn main() {
     // ICE trigger
     (G(PhantomData))(1);
diff --git a/src/test/run-pass/overloaded-calls-simple.rs b/src/test/run-pass/overloaded-calls-simple.rs
index d18a91c5452..b20c80dc4c9 100644
--- a/src/test/run-pass/overloaded-calls-simple.rs
+++ b/src/test/run-pass/overloaded-calls-simple.rs
@@ -18,24 +18,38 @@ struct S1 {
 }
 
 impl FnMut<(i32,)> for S1 {
-    type Output = i32;
     extern "rust-call" fn call_mut(&mut self, (z,): (i32,)) -> i32 {
         self.x * self.y * z
     }
 }
 
+impl FnOnce<(i32,)> for S1 {
+    type Output = i32;
+    extern "rust-call" fn call_once(mut self, args: (i32,)) -> i32 {
+        self.call_mut(args)
+    }
+}
+
 struct S2 {
     x: i32,
     y: i32,
 }
 
 impl Fn<(i32,)> for S2 {
-    type Output = i32;
     extern "rust-call" fn call(&self, (z,): (i32,)) -> i32 {
         self.x * self.y * z
     }
 }
 
+impl FnMut<(i32,)> for S2 {
+    extern "rust-call" fn call_mut(&mut self, args: (i32,)) -> i32 { self.call(args) }
+}
+
+impl FnOnce<(i32,)> for S2 {
+    type Output = i32;
+    extern "rust-call" fn call_once(self, args: (i32,)) -> i32 { self.call(args) }
+}
+
 struct S3 {
     x: i32,
     y: i32,
diff --git a/src/test/run-pass/overloaded-calls-zero-args.rs b/src/test/run-pass/overloaded-calls-zero-args.rs
index 78e84b9d55b..245ff6df614 100644
--- a/src/test/run-pass/overloaded-calls-zero-args.rs
+++ b/src/test/run-pass/overloaded-calls-zero-args.rs
@@ -18,12 +18,16 @@ struct S {
 }
 
 impl FnMut<()> for S {
-    type Output = i32;
     extern "rust-call" fn call_mut(&mut self, (): ()) -> i32 {
         self.x * self.y
     }
 }
 
+impl FnOnce<()> for S {
+    type Output = i32;
+    extern "rust-call" fn call_once(mut self, args: ()) -> i32 { self.call_mut(args) }
+}
+
 fn main() {
     let mut s = S {
         x: 3,
diff --git a/src/test/run-pass/unboxed-closures-fn-as-fnmut-and-fnonce.rs b/src/test/run-pass/unboxed-closures-fn-as-fnmut-and-fnonce.rs
index 0aab5be2877..aad190d0236 100644
--- a/src/test/run-pass/unboxed-closures-fn-as-fnmut-and-fnonce.rs
+++ b/src/test/run-pass/unboxed-closures-fn-as-fnmut-and-fnonce.rs
@@ -19,12 +19,20 @@ use std::ops::{Fn,FnMut,FnOnce};
 struct S;
 
 impl Fn<(i32,)> for S {
-    type Output = i32;
     extern "rust-call" fn call(&self, (x,): (i32,)) -> i32 {
         x * x
     }
 }
 
+impl FnMut<(i32,)> for S {
+    extern "rust-call" fn call_mut(&mut self, args: (i32,)) -> i32 { self.call(args) }
+}
+
+impl FnOnce<(i32,)> for S {
+    type Output = i32;
+    extern "rust-call" fn call_once(self, args: (i32,)) -> i32 { self.call(args) }
+}
+
 fn call_it<F:Fn(i32)->i32>(f: &F, x: i32) -> i32 {
     f(x)
 }
diff --git a/src/test/run-pass/unboxed-closures-fnmut-as-fnonce.rs b/src/test/run-pass/unboxed-closures-fnmut-as-fnonce.rs
index a8bb0918932..94be6406367 100644
--- a/src/test/run-pass/unboxed-closures-fnmut-as-fnonce.rs
+++ b/src/test/run-pass/unboxed-closures-fnmut-as-fnonce.rs
@@ -19,13 +19,17 @@ use std::ops::{FnMut,FnOnce};
 struct S;
 
 impl FnMut<(i32,)> for S {
-    type Output = i32;
-
     extern "rust-call" fn call_mut(&mut self, (x,): (i32,)) -> i32 {
         x * x
     }
 }
 
+impl FnOnce<(i32,)> for S {
+    type Output = i32;
+
+    extern "rust-call" fn call_once(mut self, args: (i32,)) -> i32 { self.call_mut(args) }
+}
+
 fn call_it_mut<F:FnMut(i32)->i32>(f: &mut F, x: i32) -> i32 {
     f(x)
 }
diff --git a/src/test/run-pass/unboxed-closures-infer-recursive-fn.rs b/src/test/run-pass/unboxed-closures-infer-recursive-fn.rs
index 2d1ba7f39b2..a2ab06049d6 100644
--- a/src/test/run-pass/unboxed-closures-infer-recursive-fn.rs
+++ b/src/test/run-pass/unboxed-closures-infer-recursive-fn.rs
@@ -30,13 +30,20 @@ impl<F,A,R> YCombinator<F,A,R> {
 }
 
 impl<A,R,F : Fn(&Fn(A) -> R, A) -> R> Fn<(A,)> for YCombinator<F,A,R> {
-    type Output = R;
-
     extern "rust-call" fn call(&self, (arg,): (A,)) -> R {
         (self.func)(self, arg)
     }
 }
 
+impl<A,R,F : Fn(&Fn(A) -> R, A) -> R> FnMut<(A,)> for YCombinator<F,A,R> {
+    extern "rust-call" fn call_mut(&mut self, args: (A,)) -> R { self.call(args) }
+}
+
+impl<A,R,F : Fn(&Fn(A) -> R, A) -> R> FnOnce<(A,)> for YCombinator<F,A,R> {
+    type Output = R;
+    extern "rust-call" fn call_once(self, args: (A,)) -> R { self.call(args) }
+}
+
 fn main() {
     let factorial = |recur: &Fn(u32) -> u32, arg: u32| -> u32 {
         if arg == 0 {1} else {arg * recur(arg-1)}
diff --git a/src/test/run-pass/unboxed-closures-manual-impl.rs b/src/test/run-pass/unboxed-closures-manual-impl.rs
index f1b79a1829e..439ec4af9eb 100644
--- a/src/test/run-pass/unboxed-closures-manual-impl.rs
+++ b/src/test/run-pass/unboxed-closures-manual-impl.rs
@@ -15,13 +15,17 @@ use std::ops::FnMut;
 struct S;
 
 impl FnMut<(i32,)> for S {
-    type Output = i32;
-
     extern "rust-call" fn call_mut(&mut self, (x,): (i32,)) -> i32 {
         x * x
     }
 }
 
+impl FnOnce<(i32,)> for S {
+    type Output = i32;
+
+    extern "rust-call" fn call_once(mut self, args: (i32,)) -> i32 { self.call_mut(args) }
+}
+
 fn call_it<F:FnMut(i32)->i32>(mut f: F, x: i32) -> i32 {
     f(x) + 3
 }