Code change:
The feature gate for the issue is . When constructing a value using the word "default" is repeated twice. See for additional details, including alternative solutions. <!-- Include each step required to complete the feature. Typically, this is a PR implementing a feature, followed by a PR that stabilizes the feature. However for larger features an implementation could be broken up into multiple PRs. --- [X] Implement the RFC: [ ] Adjust documentation ([see instructions on rustc-dev-guide][doc-guide]) [ ] Stabilization PR ([see instructions on rustc-dev-guide][stabilization-guide]) [ ] Update examples in the documentation that currently use to use where it makes sense. [stabilization-guide]: https://rustc-dev- [doc-guide]: https://rustc-dev- <!-- Include any open questions that need to be answered before the feature can be stabilized. --- Should the language allow direct import of trait methods, this feature becomes redundant. This addition is likely to be stabilized only when we decide that direct import of trait methods is will not be supported. <!-- Include a list of all the PRs that were involved in implementing the feature. --
modify labels to +F-defaultfreefn
You call out in the description here - but why aren't or good alternatives? They work today, if the Default trait is in scope, and it is in the prelude.
is convenient when the compiler can not infer the type. But when it can, because redundant. Here is a discussion where this was mentioned as well:
FWIW I think it is often still good style to say to communicate to the human reader the type being constructed away, which can be declared very far away in the code (even in a different file).
I do no think this change takes away that and in certain cases you have to say . The change allows you to say in cases where you are currently saying .
happens a lot in struct displays, with being as redundant as .
A bit late to the party, but why not just a in the prelude instead ? That's less code to inline for the optimizer.
I am not sure I understand exactly what are you suggesting. But if the motivation described in the issues summary is not enough, please, read the discussion in
Is there a reason why this new free function isn't in the prelude when the feature is used?
Any additions to the prelude need to go through their own RFC. The bar is quite high, to say the least.
What's the status of this feature? I've found that The Book should be updated (Appendix C - Derivable Traits) but not really sure how to proceed.
One thing that I think is worth calling out is that this is putting a free function inside the module. So in order to avoid the stutter complaint of using , it sounds like you'd have to add a somewhere in order to use . So that stutter is still there in some sense and you have to write an import for it. Granted, this gets rid of the stutter at the call site. I also want to bring up the alternative. In particular, while it of course is not a replacement to avoid the stutter in all cases, I do think it is generally better to use in lieu of either a free function or . So to me, this on its own reduces the incidence of having to write a stuttering call, and thus also reduces the importance of adding things to std that allow one to avoid the stutter. As a more general point, to be honest, I'm not a huge fan of dumping aliases to things into std. I think it invites questions like, "Wait, what's the difference between the free function and ?" And it kind of just becomes another thing that folks need to learn, and another thing where some code will undoubtedly be using and other code will just be using the free function, which are expressed as two different things in std's API. More generally, do we have other aliases like this in std already? I know we have things like and , but we've deprecated the former. I wonder if it makes more sense to talk about "let's add aliases to std" as a more general policy question. In , wrote: To be honest, this seems infrequent enough where it might be reasonable to just define an internal helper function.
Isn't the plan to have in the prelude ?
I'm not aware of that plan. Could you please link to it?
You're right my bad. It was just a reminiscence of .
We discussed this in today's meeting. The general sentiment was: We'd like to make sure that can work even in const contexts. Ping what's the status of being able to say, for a free function like , that it's if and only if there's a const impl of ? We'd like to know if that'd be possible, even if it's nightly-only. And if it is, we'd like to use that for . Assuming that's possible, those of us in the meeting were generally in favor of having , and adding it to the prelude.
it's possible and already works (not yet in bootstrap libcore though): But we are not yet confident in whether we can safely (in the stability sense) stabilize a function that uses this feature without also stabilizing something of that feature at the same time.
Are we working on the assumption that something like won't be available in the future? Or is it more that we're okay with the potential for a little duplication down the road?
If one day it becomes possible to a trait method, then I think we'd still want to export the free function , we'd just turn it into a . So I don't see any reason we should wait for that. That looks great. It'd be helpful to know if we could stabilize a function using and without first stabilizing those two features themselves, but even if that's not the case, the confirmation that this can work is good enough for me to think we should stabilize this. I'm starting an FCP to get consensus on providing the free function , and exporting it from the prelude. (This consensus does not mean we have to stabilize it immediately; we can work with const-eval to figure out if it's possible to export something based on and , or if we need to wait for those features. For now, I'd just like to confirm consensus for the general plan of providing the function and the prelude re-export.) merge
Team member has proposed to merge this. The next step is review by the rest of the tagged team members: [x] [ ] [ ] [x] [ ] [ ] No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See for info about what commands tagged team members can give me.
Oh sure, I just wanted to make sure that this was desired even in that situation. Personally I'm :+1: regardless.
This is still fairly early in the experimental stage, so I don't think we should stabilize anything using it just yet.
The primary blocker from our meeting was whether it would be possible, not necessarily doing so right away.
I think my general lean is in line with comment and comment . I'm hesitant to add alternative ways to invoke the same functionality without strong justification, and I don't believe that "reducing visual noise" is a sufficiently strong justification in this case. Also, given indicating that it would likely be easy to add support for to the language and the fact that as far as I can tell we've not ruled that out, other than that nobody has attempted it, I would prefer seeing an attempt to implement support for importing trait methods in general to stabizing this API.
since its been a month and a half and we're still only at 2/6 in favor of merging, I'm going to go ahead and close the FCP, though I will not be starting a new FCP to close the tracking issue because I still think we should work to resolve this issue through trait method imports or at least rule that out as a possibility. cancel
proposal cancelled.
Related discussion on Internals (some people here are proposing a lint to recommend over , to clear up some confusion related to the functional update syntax, which would make an anti-pattern right out of the gate):
Bevy 0.7 introduced a similar function in their own prelude: , bevyengine/bevy.
Just wanted to say that I very much enjoy using bevy's function. It's fairly common in struct initialisation, so it does make a tangible difference to the enjoyment of rust have such a shorthand.
There are tons of other traits that contains a single method, for example . Do we want to create free functions for all the traits?
No, just this one. It's more readable than .. Default::default()
I have included in my utils. You can write: and get correct type suggestions on the fly. I like this style personally.
There is really no need for this extra function, just simply add to the prelude
Trait methods can't be imported directly
This came up with Bevy uses of a free function: The lint : "function cannot return without recursing" is not raised by using Does not raise a warning: Raises a warning: This is
There is one thing that I noticed: When I initialize a struct I often start with and then jump to the definition of (using rust-analyzer) to see what the defaults are and to decide which fields I want to change. That's possible with and , but that's not possible with the free function (e.g. the one from bevy, it just jumps to definition inside the bevy crate). That's very unfortunate because from a visual perspective I would prefer .
That’s ok, IDEs will get smarter. It’s not a reason to not do it. On Fri, 23 Jun 2023 at 19:12, Jakob Schikowski
We discussed this in the libs-api meeting today. We would prefer to see a language feature to import the method directly. The language team seems to be open to this, but someone needs to write up a language proposal and drive the design of this feature. Since we are unlikely to stabilize the function as-is, we would like to remove it from the standard library. fcp close
Team member has proposed to close this. The next step is review by the rest of the tagged team members: [x] [x] [x] [ ] [x] No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See for info about what commands tagged team members can give me.
I am not familiar with the removal process, but if it is just another issue with, essentially, a revert of the original change, I can do that. Though, if someone happens to have a link to an example, I would appreciate it. Was the consensus to remove it now, or after support for importing trait methods is to the language? If someone wants to mentor me in writing a language proposal, I could probably do that as well. As I have not participated in the language processes in the past, it is not very likely I would manage it by myself.
:bell: This is now entering its final comment period, as per the . :bell:
The final comment period, with a disposition to close, as per the , is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.
So, the feature has been removed in favor of a language change, but without actually formally proposing the language change? Disappointing.
TL;DR
maybe we can have a language feature (alias) specifically for when creating structs with to support which expands to . This makes sense because the language already has this syntax is places such as pattern matching
has there been any followup RFC/tracking issue for an eventual syntax?
For what it's worth, is an open issue on this, maybe we could have some discussion there to move things forward.

Related discussion:
text: <del> # `default_free_fn` The tracking issue for this feature is: [#73014] [#73014]: https://github.com/rust-lang/rust/issues/73014 ------------------------ Adds a free `default()` function to the `std::default` module.  This function just forwards to [`Default::default()`], but may remove repetition of the word "default" from the call site. [`Default::default()`]: ../../std/default/trait.Default.html#tymethod.default Here is an example: ```rust #![feature(default_free_fn)] use std::default::default; #[derive(Default)] struct AppConfig { foo: FooConfig, bar: BarConfig, } #[derive(Default)] struct FooConfig { foo: i32, } #[derive(Default)] struct BarConfig { bar: f32, baz: u8, } fn main() { let options = AppConfig { foo: default(), bar: BarConfig { bar: 10.1, ..default() }, }; } ``` </del>