You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
FnMut not implemented for mutable FnMut implementors #23015
foo.rs:5:5: 5:8 error: the trait `core::ops::Fn<()>` is not implemented for the type `&mut [closure foo.rs:4:18: 4:23]` [E0277]
foo.rs:5 foo(&mut cb);
^~~
error: aborting due to previous error
The unfortunate error message is covered by another issue, but this seems like an unfortunate limitation. I tried to implement this but got coherence violations. I also implemented this "halfway" and got compile errors due to legitimate coherence violations which sprang up. I believe we have some hardwired impls of these traits in the compiler, but I'd like to make sure we have our story straight on these.
So I've implemented this but I found two surprising interactions.
First, impls like FnMut for &mut F where F : FnMut conflict with the core/str/pattern impls. I fixed this by removing the "autoderef" Pattern impl and adding an impl of Pattern for &String.
Second, the autoderef loop for calls, currently, always autorefs. This is because it's based around the operator code and not the normal method lookup. This probably needs to be changed though because otherwise if we have x: &mut F where F:FnMut, you can't call x() -- you have to declare mut x: &mut F. The reason is that x() gets elaborated to <&mut F as FnMut()>::call_mut(&mut x) rather than <F as FnMut()>::call_mut(&mut *x). The latter is what we get today and probably what we want.
Activity
laijs commentedon Mar 4, 2015
These code can't work?:
I know this will leave another four types without implmenting any Fn*.
the left four types:
&mut Fn, &FnMut, &FnOnce, &mut FnOncetheemathas commentedon Mar 5, 2015
Already discussed in http://internals.rust-lang.org/t/implement-closure-traits-on-t-when-t-implements-them/1638
You can workaround with
foo(||cb())in most cases.pnkfelix commentedon Mar 5, 2015
seems likely fixable in backwards compatible manner.
P-high, not 1.0.
nikomatsakis commentedon Mar 5, 2015
I'm working hard on this.
nikomatsakis commentedon Mar 17, 2015
So I've implemented this but I found two surprising interactions.
First, impls like
FnMut for &mut F where F : FnMutconflict with thecore/str/patternimpls. I fixed this by removing the "autoderef" Pattern impl and adding an impl ofPattern for &String.Second, the autoderef loop for calls, currently, always autorefs. This is because it's based around the operator code and not the normal method lookup. This probably needs to be changed though because otherwise if we have
x: &mut FwhereF:FnMut, you can't callx()-- you have to declaremut x: &mut F. The reason is thatx()gets elaborated to<&mut F as FnMut()>::call_mut(&mut x)rather than<F as FnMut()>::call_mut(&mut *x). The latter is what we get today and probably what we want.rollup merge of rust-lang#23282: nikomatsakis/fn-trait-inheritance
Merge pull request rust-lang#23015 from so1ve/fix/22995