Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add (unstable) FnBox trait as a nicer replacement for Thunk. #23939

Merged
merged 3 commits into from
Apr 2, 2015

Conversation

nikomatsakis
Copy link
Contributor

Add (unstable) FnBox trait as a nicer replacement for Thunk. The doc comment includes a test that also shows how it can be used.

f? @aturon
f? @alexcrichton

@rust-highfive
Copy link
Contributor

r? @brson

(rust_highfive has picked a reviewer for you, use r? to override)

@nikomatsakis nikomatsakis changed the title [RFC] Add (unstable) FnBox trait as a nicer replacement for Thunk. [WIP] Add (unstable) FnBox trait as a nicer replacement for Thunk. Apr 1, 2015
@nikomatsakis nikomatsakis assigned alexcrichton and unassigned brson Apr 1, 2015
@nikomatsakis
Copy link
Contributor Author

r? @alexcrichton

@bors
Copy link
Collaborator

bors commented Apr 1, 2015

☔ The latest upstream changes (presumably #23936) made this pull request unmergeable. Please resolve the merge conflicts.

@nikomatsakis
Copy link
Contributor Author

Hmm, encountered an obstacle. Investigating now.

@nikomatsakis
Copy link
Contributor Author

OK, so, there is an obstacle that I'm not sure how best to rectify, though it's also not a strict blocker. Just make the FnBox story less good than I hoped it was. (Of course, FnBox has always been seen as a kind of temporary work-around.)

If you have a type like x: Box<FnBox(&mut Foo)> (note the bound region there), you can't call it with x() notation, you must write x.call_box((arg,)). The reason is that the impl is for Box<FnBox<A>> which is less polymorphic than Box<for<'a> FnBox<(&'a mut Foo,)>>. The compiler's normal "instantiate polymorphic region" logic doesn't help here, because the call is being redirected through an impl, which requires that Box<FnBox<A>> == Box<for<'a> FnBox<(&'a mut Foo,)>> for some A that is just not possible.

There are two workarounds. You can manually upcast:

let x: Box<FnBox<(&mut Foo,), Output=()>> = x;

which works because Box is covariant, or just use call_box directly.

(Interestingly, this would be a kind of use case for variance on traits (that I just opened a PR to remove) except that FnBox winds up being invariant due to associated types, kind of proving my point that it's not buying us as much as it should.)

@@ -958,7 +959,7 @@ pub fn run_test(opts: &TestOpts,
}
DynMetricFn(f) => {
let mut mm = MetricMap::new();
f.invoke(&mut mm);
f.call_box((&mut mm,)); // TODO unfortunate
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this may need to be "FIXME" to get past make tidy

@alexcrichton
Copy link
Member

Nice! r=me with a few nits

I'm ok with having to use unstable syntax to use an unstable feature :)

@nikomatsakis nikomatsakis force-pushed the fn-box branch 2 times, most recently from 1d599ca to aa4d829 Compare April 1, 2015 18:02
@aturon aturon mentioned this pull request Apr 1, 2015
91 tasks
@aturon
Copy link
Member

aturon commented Apr 1, 2015

LGTM as well. We can discuss the stabilization story at some point during the beta period.

comment includes a test that also shows how it can be used.
for `Box<FnBox()>`. I found the alias was still handy because it is
shorter than the fully written type.

This is a [breaking-change]: convert code using `Invoke` to use `FnBox`,
which is usually pretty straight-forward. Code using thunk mostly works
if you change `Thunk::new => Box::new` and `foo.invoke(arg)` to
`foo(arg)`.
@nikomatsakis nikomatsakis changed the title [WIP] Add (unstable) FnBox trait as a nicer replacement for Thunk. Add (unstable) FnBox trait as a nicer replacement for Thunk. Apr 1, 2015
@nikomatsakis
Copy link
Contributor Author

@bors r=alexcrichton cade32a

@nikomatsakis
Copy link
Contributor Author

@bors r=alexcrichton 8eed73f

alexcrichton added a commit to alexcrichton/rust that referenced this pull request Apr 1, 2015
Conflicts:
	src/liballoc/boxed.rs
@alexcrichton alexcrichton merged commit 8eed73f into rust-lang:master Apr 2, 2015
@nikomatsakis nikomatsakis deleted the fn-box branch March 30, 2016 16:13
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants