-
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
Changes from 6 commits
06f87fd
c886a0a
d400320
afea13f
a778e87
1c9c699
ccd4a78
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 1,68 @@ | ||
- Feature Name: `drop_types_in_const` | ||
- Start Date: 2016-01-01 | ||
- RFC PR: (leave this empty) | ||
- Rust Issue: (leave this empty) | ||
|
||
# Summary | ||
[summary]: #summary | ||
|
||
Allow types with destructors to be used in `static` items and in `const` functions, as long as the destructor never needs to run in const context. | ||
|
||
# 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 | ||
is no longer required to be a hard error. | ||
|
||
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This section should explore different implementation strategies as well. E.g. do we use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It may not have been clear enough here - This is just to use the current |
||
[design]: #detailed-design | ||
|
||
- Lift the restriction on types with destructors being used in statics. | ||
- (Optionally adding a lint that warn about the possibility of resource leak) | ||
- Alloc instantiating structures with destructors in constant expressions, | ||
- Continue to prevent `const` items from holding types with destructors. | ||
- Allow `const fn` to return types with destructors. | ||
- Disallow constant expressions which would result in the destructor being called (if the code were run at runtime). | ||
|
||
## Examples | ||
Assuming that `RwLock` and `Vec` have `const fn new` methods, the following example is possible and avoids runtime validity checks. | ||
|
||
```rust | ||
/// Logging output handler | ||
trait LogHandler: Send Sync { | ||
// ... | ||
} | ||
/// List of registered logging handlers | ||
static S_LOGGERS: RwLock<Vec< Box<LogHandler> >> = RwLock::new( Vec::new() ); | ||
``` | ||
|
||
Disallowed code | ||
```rust | ||
static VAL: usize = (Vec::<u8>::new(), 0).1; // The `Vec` would be dropped | ||
const EMPTY_BYTE_VEC: Vec<u8> = Vec::new(); // `const` items can't have destructors | ||
|
||
const fn sample(_v: Vec<u8>) -> usize { | ||
0 // Discards the input vector, dropping it | ||
} | ||
``` | ||
|
||
# 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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This drawback is not necessary. I.e. we could use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Life after main has the same problems as life before main, destruction order in particular. (The same set of problems apply to thread locals.) |
||
|
||
# Alternatives | ||
[alternatives]: #alternatives | ||
|
||
- Runtime initialisation of a raw pointer can be used instead (as the `lazy_static` crate currently does on stable) | ||
- On nightly, a bug related to `static` and `UnsafeCell<Option<T>>` can be used to remove the dynamic allocation. | ||
|
||
Both of these alternatives require runtime initialisation, and incur a checking overhead on subsequent accesses. | ||
|
||
# Unresolved questions | ||
[unresolved]: #unresolved-questions | ||
|
||
- TBD |
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
)