rust-lang / rust-lang/rust

Implement `Default` for singleton function item types

Open
#130,884 1 comment 4 reactions 1 assignee View on GitHub

@compiler-errors is already working on this.

Since Sep 26, 2024.

A-trait-system C-feature-request T-lang
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

Context

I have recently found myself doing some work that involves storing function-like items in structs along with other data, which involves a field of some generic type F that is going to implement some Fn trait. Such a struct might look something like this:

struct DeferredMappedData<S, T, F> {
    data: S,
    function: F,
    _phantom: PhantomData<T>,
}

with the idea that F: Fn(S) -> T or similar. Thus, such a type would typically support things like

fn eval(&self) -> T { //... }
fn new(data: S, function: impl Fn(S) -> T) -> Self { //... }

and so on.

The problem

An issue that I've run into is that F is very often the type of a function item, in which case one would hope that the actual value of the function could be inferred from the type parameter and nothing else, which is essentially the same thing as implementing Default. This would allow me, for example, to write code like this:

impl<S, T, F: Default> DeferredMappedData<S, T, F> {
    fn from_data(data: S) -> Self {
        Self {
            data,
            function: Default::default(),
            _phantom: PhantomData,
        }
    }
}

However, that is not the case, and code like this is, at the moment, effectively worthless, since function item types are not Default.

Of course, this shortfall doesn't always arise so explicitly; for instance, the Default bound could be introduced by a #[derive] macro or similar. In my particular case, this actually has to do with building values through reflection (and hence possibly during things like deserialization).

Workarounds

As far as I'm aware, the only real way to work around this is to manually monomorphize away F yourself (and hence bake the explicit function into the implementations of the methods). If you only care about some small number of values of F, maybe that's acceptable (e.g. using macros), but in any kind of general interface, there is effectively no workaround for this at all, to my knowledge.

Aside

Being able to actually name these function types would also be valuable — even with the Default implementation, you still can't name the type of the monomorphized struct, for instance. My understanding is that there are efforts towards that kind of thing, like being able to alias the names of automatically inferred types, but I'm not really in the loop there. Again, I'm certainly not a compiler person or anything, but I think that, independently, being able to explicitly name the singleton types of function items would also be nice. (Basically, I don't see why the compiler should necessarily have to infer this for me at all times.)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.