Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Implement Default for &Option #140808

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

Open
camsteffen wants to merge 1 commit into rust-lang:master
base: master
Choose a base branch
Loading
from camsteffen:default-for-option-ref

Conversation

Copy link
Contributor

@camsteffen camsteffen commented May 8, 2025

Pretty straightforward, but here is some justification:

I wasn't able to derive Default for my struct containing a &Option<MyType> because I can't implement Default for &Option<MyType> because of the orphan rule. I suppose this is an unusual case because Option<&T> is generally preferred over &Option<T>. But I think adding this is justified for a couple reasons. 1) It removes an unnecessary speed bump. 2) I think there are times when &Option<T> is preferable. In my project I am creating and passing around &Option<MyType> in a lot of places, but only actually using MyType in one place. So it's not worth the ergonomic cost of having to write build_mytype(...).as_ref() instead of &build_mytype(...) in many places.

r? libs

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels May 8, 2025
@camsteffen camsteffen changed the title (削除) Add Default for &Option (削除ここまで) (追記) Implement Default for &Option (追記ここまで) May 8, 2025
Copy link
Member

jieyouxu commented May 8, 2025

r? libs-api

@rustbot rustbot added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label May 8, 2025
Copy link
Contributor Author

Looking at this more closely, this is not as obvious as I thought. There doesn't seem to be any precedent in std for implementing Default for any reference types excluding unsized types like &str. Is this a slippery slope of adding impl Default to references to all std types? Or is there an obvious solution I'm missing? Also I realized that feature(default_field_values) would be good enough for the use case I encountered. So I'm unsure, but still wonder if adding this is worth it because of the ubiquity of Option and the orphan rule. (I probably should have started a discussion instead of a PR, apologies)

Copy link
Member

I'm honestly surprised that this works at all. Assuming it does work, it seems reasonable to add.

@joshtriplett joshtriplett added the I-libs-api-nominated Nominated for discussion during a libs-api team meeting. label Jul 1, 2025
Copy link
Contributor

tgross35 commented Jul 1, 2025

I wonder, would it be possible to make the derive smarter to handle all reference types? Rather than needing to add this on a case-by-case basis.

@joshtriplett joshtriplett removed the T-libs Relevant to the library team, which will review and decide on the PR/issue. label Jul 1, 2025
Copy link
Member

@rfcbot merge

Copy link

rfcbot commented Jul 1, 2025
edited
Loading

Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members:

Concerns:

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 this document for info about what commands tagged team members can give me.

@rfcbot rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. labels Jul 1, 2025
Copy link
Member

Amanieu commented Jul 1, 2025

I'm concerned about the forward-compatibility of this with a more general Default impl for all T: const Default (using const traits). Specifically, this would probably at least require an additional T: Freeze and T: !Drop bound, which would make the future impl incompatible with this one.

@rfcbot concern const-trait

clarfonthey reacted with thumbs up emoji

Comment on lines +2098 to +2104
impl<'a, T> Default for &'a Option<T> {
/// Returns `&None`
#[inline]
fn default() -> &'a Option<T> {
&None
}
}
Copy link
Member

@scottmcm scottmcm Jul 5, 2025

Choose a reason for hiding this comment

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

ymmv: I'm pretty sure you can remove the explicit lifetime here by writing it as

Suggested change
impl<'a,T> Default for &'aOption<T> {
/// Returns `&None`
#[inline]
fn default() -> &'aOption<T> {
&None
}
}
impl<T> Default for &Option<T> {
/// Returns `&None`
#[inline]
fn default() -> Self {
&None
}
}

camsteffen and DavidSkrundz reacted with thumbs up emoji
@Amanieu Amanieu removed the I-libs-api-nominated Nominated for discussion during a libs-api team meeting. label Jul 8, 2025
Copy link
Contributor

Regarding the concern about forward-compatibility with what we might want with const traits, a Freeze and !Drop bound, etc.:

cc @oli-obk @fee1-dead @compiler-errors @p-avital

Copy link
Contributor

oli-obk commented Jul 8, 2025

This could be experimented with when #134628 lands (it's already approved)

Copy link
Contributor Author

Specifically, this would probably at least require an additional T: Freeze and T: !Drop bound

I think that impl should not exist because of those constraints? This impl on &Option<T> does not have any constraints on T because the compiler knows that the expression None does not contain a T.

Copy link

tmke8 commented Jul 28, 2025
edited
Loading

I think the point is to add an additional (though in this specific case unnecessary) bound on the impl so that in the future, a more general impl can still be added that is still compatible with this one. (The more general impl would implement Default for all &T where T has a default that can be generated with const code, as is the case for Option<...> where the default is just a None.)

Copy link
Contributor Author

I feel like I'm missing something here. Isn't it not possible to add an impl for all &T because that would break any user's impl for &WhateverType?

Copy link
Member

dtolnay commented Jul 28, 2025

No. No user-defined type currently implements const Default so adding impl<T: const Default + ???> Default for &T would not overlap with any user impl.

Copy link
Contributor Author

I see. Thanks for spelling that out. 😅

Back to my previous comment then, if we add impl<T: const Default + Freeze> const Default for &T, that would prevent us from writing:

fn test() -> &'static Option<MyType> {
 Default::default() // error: not MyType is not Freeze
}
#[derive_const(Default)]
enum MyType {
 Foo(Cell<u32>),
 #[default]
 Bar
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Reviewers

@scottmcm scottmcm scottmcm left review comments

Labels
disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /