Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upRFC - Allow Drop types in statics/const functions #1440
Conversation
thepowersgang
added some commits
Jan 1, 2016
nagisa
reviewed
Jan 1, 2016
| # 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 |
This comment has been minimized.
This comment has been minimized.
nagisa
Jan 1, 2016
Contributor
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?
This comment has been minimized.
This comment has been minimized.
thepowersgang
Jan 1, 2016
Author
Contributor
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)
nagisa
reviewed
Jan 1, 2016
| Allowing types with destructors to be directly used in `const` functions and stored in `static`s will remove the need to have | ||
| runtime-initialisation for global variables. | ||
|
|
||
| # Detailed design |
This comment has been minimized.
This comment has been minimized.
nagisa
Jan 1, 2016
Contributor
This section should explore different implementation strategies as well. E.g. do we use .ctors and .dtors sections (that’s what c++ does) which allows for life-before-main (which we’ve been very reluctant about allowing) or do we employ scheme similar to lazy_static! (initialize on first use)?
This comment has been minimized.
This comment has been minimized.
thepowersgang
Jan 1, 2016
Author
Contributor
It may not have been clear enough here - This is just to use the current const structure (no life before main, no life after it) to do compile-time construction of objects that support it.
nagisa
reviewed
Jan 1, 2016
| # Drawbacks | ||
| [drawbacks]: #drawbacks | ||
|
|
||
| Destructors do not run on `static` items (by design), so this can lead to unexpected behavior when a type's destructor has effects outside the program (e.g. a RAII temporary folder handle, which deletes the folder on drop). However, this can already happen using the `lazy_static` crate. |
This comment has been minimized.
This comment has been minimized.
nagisa
Jan 1, 2016
Contributor
This drawback is not necessary. I.e. we could use .dtors section which would execute all the necessary destructors for statics once we exit from main.
This comment has been minimized.
This comment has been minimized.
petrochenkov
Jan 1, 2016
Contributor
Life after main has the same problems as life before main, destruction order in particular. (The same set of problems apply to thread locals.)
This comment has been minimized.
This comment has been minimized.
|
The RFC does not address the case of objects in thread local storage. |
This comment has been minimized.
This comment has been minimized.
|
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 |
This comment has been minimized.
This comment has been minimized.
|
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 |
This comment has been minimized.
This comment has been minimized.
|
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 |
This comment has been minimized.
This comment has been minimized.
|
@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 |
This comment has been minimized.
This comment has been minimized.
|
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 |
This comment has been minimized.
This comment has been minimized.
|
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. |
This comment has been minimized.
This comment has been minimized.
|
The problem is that you can take the address of a constant, in which case it is very unobvious when the destructor is run. |
This comment has been minimized.
This comment has been minimized.
|
@arielb1 Oh, I forgot about taking a reference to a constant value, that's something we can prevent relatively easily (we already allow |
This comment has been minimized.
This comment has been minimized.
|
Mm it's a gotcha sure, but follows from const items' rvalue semantics. Maybe a lint would suffice? |
This comment has been minimized.
This comment has been minimized.
|
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. |
nrc
added
the
T-lang
label
Jan 4, 2016
nikomatsakis
self-assigned this
Jan 7, 2016
thepowersgang
referenced this pull request
Mar 8, 2016
Closed
Allow types with destructors in static variables #1111
nikomatsakis
added
the
I-nominated
label
Mar 9, 2016
This comment has been minimized.
This comment has been minimized.
|
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. |
This comment has been minimized.
This comment has been minimized.
|
It should be backwards compatible if we start with it unspecified, since we can later change to a guarantee in either direction, right? |
This comment has been minimized.
This comment has been minimized.
|
@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. |
This comment has been minimized.
This comment has been minimized.
|
I thought "no life outside of |
This comment has been minimized.
This comment has been minimized.
|
Note that Thinking about it more, I think we can make |
This comment has been minimized.
This comment has been minimized.
|
I agree with @nikomatsakis: this is a very desirable feature, and the approach proposed in the RFC seems reasonable, but our const/static system has been thorny in the past and we still don't have crystal clear plans for where we want to go with const-eval in particular. However, given that this functionality can be feature-gated, I'm in favor of going forward on an experimental basis, but waiting to stabilize until we have a better sense of our overall const/static vision. I'll also note that while leaking dtors is indeed allowed in safe code, it's also rare today -- and almost always a bug. It would be good to flesh out the lint side of this story -- I could imagine warning by default on any dtor leaked by a static, with the ability to apply an attribute to a type that flags it as "leaks are harmless", or something like that. Certainly leaking seems far preferable to trying to work out a general system for life-after-main. |
This comment has been minimized.
This comment has been minimized.
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() {} |
This comment has been minimized.
This comment has been minimized.
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 comment has been minimized.
This comment has been minimized.
This is just as much of a leak as exiting by calling |
This comment has been minimized.
This comment has been minimized.
|
@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. |
This comment has been minimized.
This comment has been minimized.
|
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 |
This comment has been minimized.
This comment has been minimized.
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. |
This comment has been minimized.
This comment has been minimized.
|
@arielb1 Either this RFC or the rvalue promotions one has to specify how the two features will interact, before this RFC is implemented. |
This comment has been minimized.
This comment has been minimized.
|
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. |
This comment has been minimized.
This comment has been minimized.
|
@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. :) |
This comment has been minimized.
This comment has been minimized.
|
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. |
nikomatsakis
referenced this pull request
Apr 22, 2016
Closed
permit `Drop` types in constants (tracking issue for RFC #1440) #33156
This comment has been minimized.
This comment has been minimized.
|
Tracking issue: rust-lang/rust#33156 If you'd like to keep following the development of this feature, please subscribe to that issue, thanks! :) |
nikomatsakis
added a commit
to nikomatsakis/rfcs
that referenced
this pull request
Apr 22, 2016
nikomatsakis
merged commit ccd4a78
into
rust-lang:master
Apr 22, 2016
This comment has been minimized.
This comment has been minimized.
|
Yay! |
This was referenced Nov 16, 2016
This comment has been minimized.
This comment has been minimized.
|
From the RFC:
What is the reason for this? I was hoping to use |
This comment has been minimized.
This comment has been minimized.
|
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. |
SergioBenitez
added a commit
to SergioBenitez/rfcs
that referenced
this pull request
Dec 13, 2016
SergioBenitez
referenced this pull request
Dec 13, 2016
Merged
Amend #1440: allow `const` items to contain drop types. #1817
This comment has been minimized.
This comment has been minimized.
|
I've created a PR (#1817) to amend the RFC to support drop types in |
thepowersgang commentedJan 1, 2016
This addresses #913 and rust-lang/rust#30667
rendered