-
Notifications
You must be signed in to change notification settings - Fork 48
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
A FunctionPointer
trait to represent all fn
types
#23
Comments
Error: This repository is not enabled to use triagebot. Please let |
FunctionPointer
trait to represent all fn
types
I have tagged this as "help-wanted" because I'm looking for someone to help push this design over the finish line. I would be happy to serve as the "liaison", in other words, but we need a lea! You can find some earlier discussion on this zulip stream. |
This comment has been minimized.
This comment has been minimized.
This issue is not meant to be used for technical discussion. There is a Zulip stream for that. Use this issue to leave procedural comments, such as volunteering to review, indicating that you second the proposal (or third, etc), or raising a concern that you would like to be addressed. |
Discussed in the lang-team meeting:
But for now we will close. |
WARNING
The Major Change Process was proposed in RFC 2936 and is not yet in
full operation. This template is meant to show how it could work.
Proposal
Summary
Create a
FunctionPointer
trait that is "fundamental" (in the coherence sense) and built-in to the compiler. It is automatically implemented for allfn
types, regardless of any other details (ABI, argument types, and so forth).Motivation
You can't write an impl that applies to any function pointer
It is not possible to write an impl that is parameteric over all fn types today. This is for a number of a reasons:
We are unlikely to ever make it possible to write an impl generic over all of those things.
And yet, there is a frequent need to write impls that work for any function pointer. For example, it would be nice if all function pointers were
Ord
, just as all raw pointers areOrd
.To work around this, it is common to find a suite of impls that attempts to emulate an impl over all function pointer types. Consider this code from the
trace
crate, for example:Or this code in the standard library.
Bug fixes in rustc endanger existing approaches
As part of the work to remove the leak-check in the compiler, we introduced a warning about potential overlap between impls like
This is a complex topic. Likely we will ultimately accept those impls as non-overlapping, since wasm-bindgen relies on this pattern, as do numerous other crates -- though there may be other limitations. But many of the use cases where those sorts of impls exist would be better handled with an opaque
FunctionPointer
trait anyhow, since what they're typically really trying to express is "any function pointer" (wasm-bindgen is actually somewhat different in this regard, as it has a special case for fns that taken references that is distinct from fns that taken ownership).Proposal
Add in a trait
FunctionPointer
that is implemented for anyfn
type (but onlyfn
types). It is built-in to the compiler, tagged as#[fundamental]
, and does not permit user-defined implementations. It offers a core operation,as_usize
, for converting to ausize
, which in turn can be used to implement the various built-in traits:In terms of the implementation, this would be integrate into the rustc trait solver, which would know that only
fn(_): FunctionPointer
.As with
Sized
, no user-defined impls would be permitted.Concerns and alternative designs
#[fundamental]
trait should handle that, but we have to experiment to see how smart the trait checker is.usize
?dlsym
returns a pointer, so in practice this is a pretty hard requirement.fn
tousize
(or to cast withas
), so to some extent we've already baked in this dependency.dyn Trait
and friends?fn
types, since there is no way to be generic over all the different sorts of bound regions one might have (e.g., overfor<'a> dyn Fn(&'a u32)
and so forth).fn
types, their size is not fixed, soas_usize
could not work, which might argue for the "extended set of operations" approach.&dyn Fn()
forfn()
.DynType
trait would be a good addition.FnDef
types (the unique types for each function)FunctionPointer
apply toFnDef
types, that can be an ergonomic win and quite useful.as_usize
could trigger us to reify a function pointer.FnDef
is not, in fact, a function pointer, just something that could be used to create a function pointer.FunctionPointer
trait, so thatas_usize
and friends can be used from const functionsAlternative designs
Instead of the
as_usize
method, we might have methods likeord(Self, Self) -> Ordering
that can be uesd to implement the traits. That set can grow over time since no user-defined impls are permitted.This is obviously less 'minimal' but might work better (as noted above) if we extend to exotic platforms or for
dyn
types.However, it may be that there is extant code that relies on converting fn pointers to
usize
and such code could not be converted to usefn
traits.The Major Change Process
Once this MCP is filed, a Zulip topic will be opened for discussion. Ultimately, one of the following things can happen:
You can read [more about the lang-team MCP process on forge].
Comments
This issue is not meant to be used for technical discussion. There is a Zulip stream for that. Use this issue to leave procedural comments, such as volunteering to review, indicating that you second the proposal (or third, etc), or raising a concern that you would like to be addressed.
The text was updated successfully, but these errors were encountered: