-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
RFC - Allow Drop types in statics/const functions #1440
RFC - Allow Drop types in statics/const functions #1440
Conversation
# Motivation | ||
[motivation]: #motivation | ||
|
||
Most collection types do not allocate any memory when constructed empty. With the change to make leaking safe, the restriction on `static` items with destructors |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean some. @gankro, I believe, explicitly expressed the intent to specify that we only will have allocation less new
when it doesn’t hurt performance/implementation complexity or something like that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point I guess. I had forgotten about the BTree collections (which, looking at the source, do allocate on 'new'). That said, there's still a lot of them that don't allocate until data is added (Vec
/String
, HashMap
, LinkedList
)
The RFC does not address the case of objects in thread local storage. |
To clarify for those who have jumped to conclusions - This RFC does not change the current stance on life-after-main. It fully accepts that Drop types placed in |
…destructors will never run, acknowledge `.dtors` as alternative
The confusion around destruction order is not the main problem, but the actual safety of the safety (accessing globals after they've been dropped). Thread locals in Sadly, such a scheme doesn't map directly to multi-threaded globals, as you need locks instead of mere flags. However, Therefore, a proper solution arises: a Is it worth it? Doubtful, given how globals would be dropped just before the process is destroyed. cc @aturon |
It's odd that const items cannot contain the return values of const functions in all cases. (At least in one case proposed by this RFC.) On the one hand this makes |
@mahkoh That's because it's impossible to check that property from the type, i.e. the body of a Whereas we already compute "had Therefore, computing "has Allowing OTOH, the restriction on I felt that |
What exactly is meant by the body of a const fn not being a part of the public API? I am quite sure that it is a part of it in basically the same way the body of a regular fn is part of the public API - code that can call it can depend on its behaviour (but unlike non-const fns, problems here can cause compilation failures in addition to runtime failures). 1 for having unrestricted statics with destructors (as I said several times, it is perfectly legal to exit with |
We don't require const items to be Copy, right? If we indeed don't, it should already be clear that using a const item is more flexible/different than a move of a normal value—a normal move would be disallowed. I don't think allowing Drop const items would add more confusion then. |
The problem is that you can take the address of a constant, in which case it is very unobvious when the destructor is run. |
@arielb1 Oh, I forgot about taking a reference to a constant value, that's something we can prevent relatively easily (we already allow |
Mm it's a gotcha sure, but follows from const items' rvalue semantics. Maybe a lint would suffice? |
I'm definitely in favor of this RFC. While it is recommended to avoid statics, sometimes you just need statics, and the limitation on no Drop types was rather restrictive in the face of leaking being considered safe. |
Discussed in the @rust-lang/lang meeting. Everyone felt in favor of this in principle, though none of us have had time to read the RFC in detail (it's not clear to me whether there are grey areas left uncovered). One question was whether we want to guarantee dtors won't run or leave it unspecified. |
It should be backwards compatible if we start with it unspecified, since we can later change to a guarantee in either direction, right? |
@retep998 Yeah, I made a similar point during the meeting. But it'd probably be a good idea to at least have a good sense of the overall contour here and what our long-term plans may be. |
I thought "no life outside of |
Note that Thinking about it more, I think we can make |
Uh, no, it doesn't, at least not reliably: struct Foo(u64, u64);
struct Unit(Foo);
static FOO: Unit = Unit((&BAR).0);
static BAR: Unit = Unit(Foo(0,0));
fn main() {} |
We do rvalue promotion purely as an optimization today, don't we (except for empty arrays which are not affected by this)? I don't think we actually specified anything here. |
This is just as much of a leak as exiting by calling |
@arielb1 Right, by "has an initializer" I meant that "the The interactions with rvalue promotions are that, if we don't want to kill it, we have to ensure it preserves semantics. |
Again: the invariant Drop statics break is that there is no accessible data with destructors after It is somewhat useful if you want to use |
I still don't see what rvalue promotions have to do with this. Rvalue promotions are supposed to not change the semantics of code that compiles without them in any case. Given that promoted rvalues are neither statics nor constants, I don't see how this RFC applies. |
@arielb1 Either this RFC or the rvalue promotions one has to specify how the two features will interact, before this RFC is implemented. |
I don't see how these 2 features interact. This affects consts and statics. Rvalue promotion affects rvalues. The code might be shared, but rvalues are neither consts nor statics. They might be using a similar code-path, but they are clearly distinct. In any case, the rvalue promotions RFC was not accepted yet. |
@arielb1: I think the argument here is "If a rvalue can be promoted it could also usually be written as a const", which amounts to the In my opinion it seems clear that promotions should not change the drop semantic inside functions, and I'd be happy to add wording in that regard to #1414. :) |
Huzzah! The @rust-lang/lang team has decided to accept this RFC. In our discussion, the feeling was the semantics here are clearly underspecified, but that this is somewhat true of constants in general, and that exploring the problem in practice was the best way to uncover complications. Naturally we should be careful with stability here to avoid unintentionally stabilizing unsupportable semantics. The core thrust of this RFC, though, that statics can have types that would require destructing, but which never get run, seems unproblematic. |
Tracking issue: rust-lang/rust#33156 If you'd like to keep following the development of this feature, please subscribe to that issue, thanks! :) |
Yay! 😄 |
From the RFC:
What is the reason for this? I was hoping to use |
I believe this was trying to minimize the scope of the RFC and potential confusion: while it would be perfectly safe to duplicate a constant, each use would run the destructor once which may be unexpected. |
I've created a PR (#1817) to amend the RFC to support drop types in |
Amend #1440: allow `const` items to contain drop types.
This addresses #913 and rust-lang/rust#30667
rendered