Skip to content
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

Amend #1440: allow const items to contain drop types. #1817

Merged
merged 3 commits into from
Jul 25, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions text/1440-drop-types-in-const.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,27 @@
# 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.
Allow types with destructors to be used in `static` items, `const` items, and `const` functions.

# Motivation
[motivation]: #motivation

Some of the collection types do not allocate any memory when constructed empty (most notably `Vec`). With the change to make leaking safe, the restriction on `static` items with destructors
Some of the collection types do not allocate any memory when constructed empty (most notably `Vec`). With the change to make leaking safe, the restriction on `static` or `const` items with destructors
is no longer required to be a hard error (as it is safe and accepted that these destructors may never run).

Allowing types with destructors to be directly used in `const` functions and stored in `static`s will remove the need to have
Allowing types with destructors to be directly used in `const` functions and stored in `static`s or `const`s will remove the need to have
runtime-initialisation for global variables.

# Detailed design
[design]: #detailed-design

- Lift the restriction on types with destructors being used in statics.
- Lift the restriction on types with destructors being used in `static` or `const` items.
- `static`s containing Drop-types will not run the destructor upon program/thread exit.
- `const`s containing Drop-types _will_ run the destructor at the appropriate point in the program.
Copy link
Contributor

Choose a reason for hiding this comment

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

I think that we should be more specific about what "the appropriate point" is. Probably by adding a subsection to allow us to elaborate. But when I started thinking about what to write I encountered a question. I'll post it on the main thread though.

- (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).
- Disallow constant expressions that require destructors to run during compile-time constant evaluation (i.e: a `drop(foo)` in a `const fn`).
Copy link
Member

Choose a reason for hiding this comment

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

doesn't this need further amending to be consistent with the other changes in the RFC?

(This probably ties into @nikomatsakis's earlier point that we need more specifics about what "the appropriate point in the program" is...)

Copy link
Member

Choose a reason for hiding this comment

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

hmm well on further reflection I guess this text may be consistent as written. (Just need to get my head around when the destructors that are now allowed are actually getting invoked.)


## Examples
Assuming that `RwLock` and `Vec` have `const fn new` methods, the following example is possible and avoids runtime validity checks.
Expand All @@ -38,12 +38,14 @@ trait LogHandler: Send + Sync {
}
/// List of registered logging handlers
static S_LOGGERS: RwLock<Vec< Box<LogHandler> >> = RwLock::new( Vec::new() );

/// Just an empty byte vector.
const EMPTY_BYTE_VEC: Vec<u8> = 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
Expand All @@ -55,6 +57,8 @@ const fn sample(_v: Vec<u8>) -> usize {

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.

A `const` item's destructor _will_ run at each point where the `const` item is used. If a `const` item is never used, its destructor will never run. These behaviors may be unexpected.

# Alternatives
[alternatives]: #alternatives

Expand Down