Skip to content
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

fn() does not implement FnMut #15448

Closed
HeroesGrave opened this issue Jul 5, 2014 · 6 comments
Closed

fn() does not implement FnMut #15448

HeroesGrave opened this issue Jul 5, 2014 · 6 comments
Labels
A-traits Area: Trait system A-typesystem Area: The type system
Milestone

Comments

@HeroesGrave
Copy link
Contributor

This does not compile:

use std::ops::Fn;

fn foo(i: int) -> int
{
    i
}

fn main()
{
    println!("{}", foo.call(1));
}
@HeroesGrave
Copy link
Contributor Author

Even with this:

use std::ops::Fn;

fn foo(i: int) -> int
{
    i
}

fn main()
{
    println!("{}", (&foo as &Fn<int, int>).call(1));
}

I get the error:

test.rs:11:21: 11:42 error: failed to find an implementation of trait core::ops::Fn<int,int> for fn(int) -> int
test.rs:11     println!("{}", (&foo as &Fn<int, int>).call(1));
                               ^~~~~~~~~~~~~~~~~~~~~
note: in expansion of format_args!
<std macros>:2:23: 2:77 note: expansion site
<std macros>:1:1: 3:2 note: in expansion of println!
test.rs:11:5: 11:53 note: expansion site

@pcwalton
Copy link
Contributor

Nominating for 1.0, P-backcompat-lang. This is something I forgot and will be necessary for unboxed closures to work properly.

@pnkfelix
Copy link
Member

Assigning 1.0 milestone, P-backcompat-lang.

@pnkfelix pnkfelix added this to the 1.0 milestone Jul 17, 2014
@pcwalton pcwalton changed the title fn() does not implement Fn fn() does not implement FnMut Jul 19, 2014
@pcwalton
Copy link
Contributor

Updated title: FnFnMut. Since FnMut is the commonest unboxed closure, I believe it makes most sense for bare functions to implement it.

@pcwalton
Copy link
Contributor

I'm having second thoughts about this; I don't see a good way to fit the implementation well into the existing vtable infrastructure, it was never covered by an RFC as far as I know, and it isn't necessary for anything to work (just convenient in some cases). It is not clear to me that, if we do this, whether we should do this as a coercion from bare functions to unboxed closures (similar to how we do these things today) or whether it should be a special kind of vtable or... something.

Anyway I'm nominating for removal from the 1.0 milestone to reduce scope creep.

cc @nikomatsakis

@nikomatsakis
Copy link
Contributor

My initial thoughts:

  1. It'd clearly be nice for this to hold, but:
  2. It is backwards compatible to add later, and:
  3. It should be done in the library, but that:
  4. It reveals a shortcoming in the tuplization approach, because it is inconsistent.

Regarding the last point, you'd prefer to write:

impl<A,R> FnMut<A,R> for fn(A) -> R { ... }

But you can't. Given variadic generics, or if we used tuples more consistently in fn types, we'd be fine, I think.

pcwalton added a commit to pcwalton/rust that referenced this issue Jul 24, 2014
This is done entirely in the libraries for functions up to 16 arguments.
A macro is used so that more arguments can be easily added if we need.
Note that I had to adjust the overloaded call algorithm to not try
calling the overloaded call operator if the callee is a built-in
function type, to prevent loops.

Closes rust-lang#15448.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-traits Area: Trait system A-typesystem Area: The type system
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants