-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FnMut not implemented for mutable FnMut implementors #23015
Comments
These code can't work?: impl<T:FnMut> FnMut for &mut T { ... }
impl<T:Fn> Fn for &T { ... } I know this will leave another four types without implmenting any Fn*. |
Already discussed in http://internals.rust-lang.org/t/implement-closure-traits-on-t-when-t-implements-them/1638 You can workaround with |
seems likely fixable in backwards compatible manner. P-high, not 1.0. |
I'm working hard on this. |
So I've implemented this but I found two surprising interactions. First, impls like 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 |
The primary motivation here is to sidestep rust-lang#19032 -- for a time, I thought that we should improve coherence or otherwise extend the language, but I now think that any such changes will require more time to bake. In the meantime, inheritance amongst the fn traits is both logically correct *and* a simple solution to that obstacle. This change introduces inheritance and modifies the compiler so that it can properly generate impls for closures and fns. Things enabled by this PR (but not included in this PR): 1. An impl of `FnMut` for `&mut F` where `F : FnMut` (rust-lang#23015). 2. A better version of `Thunk` I've been calling `FnBox`. I did not include either of these in the PR because: 1. Adding the impls in 1 currently induces a coherence conflict with the pattern trait. This is interesting and merits some discussion. 2. `FnBox` deserves to be a PR of its own. The main downside to this design is (a) the need to write impls by hand; (b) the possibility of implementing `FnMut` with different semantics from `Fn`, etc. Point (a) is minor -- in particular, it does not affect normal closure usage -- and could be addressed in the future in many ways (better defaults; convenient macros; specialization; etc). Point (b) is unfortunate but "just a bug" from my POV, and certainly not unique to these traits (c.f. Copy/Clone, PartialEq/Eq, etc). (Until we lift the feature-gate on implementing the Fn traits, in any case, there is room to correct both of these if we find a nice way.) Note that I believe this change is reversible in the future if we decide on another course of action, due to the feature gate on implementing the `Fn` traits, though I do not (currently) think we should reverse it. Fixes rust-lang#18835. r? @nrc
…dd-impls, r=pnkfelix The primary purpose of this PR is to add blanket impls for the `Fn` traits of the following (simplified) form: impl<F:Fn> Fn for &F impl<F:FnMut> FnMut for &mut F However, this wound up requiring two changes: 1. A slight hack so that `x()` where `x: &mut F` is translated to `FnMut::call_mut(&mut *x, ())` vs `FnMut::call_mut(&mut x, ())`. This is achieved by just autoderef'ing one time when calling something whose type is `&F` or `&mut F`. 2. Making the infinite recursion test in trait matching a bit more tailored. This involves adding a notion of "matching" types that looks to see if types are potentially unifiable (it's an approximation). The PR also includes various small refactorings to the inference code that are aimed at moving the unification and other code into a library (I've got that particular change in a branch, these changes just lead the way there by removing unnecessary dependencies between the compiler and the more general unification code). Note that per rust-lang/rfcs#1023, adding impls like these would be a breaking change in the future. cc @japaric cc @alexcrichton cc @aturon Fixes rust-lang#23015.
For example this program does not compile
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.
The text was updated successfully, but these errors were encountered: