From 06f87fdd916396884b61aa143b3b572f178b7791 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 1 Jan 2016 11:28:59 +0800 Subject: [PATCH 1/7] Initial draft --- text/0000-drop-types-in-const.md | 40 ++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 text/0000-drop-types-in-const.md diff --git a/text/0000-drop-types-in-const.md b/text/0000-drop-types-in-const.md new file mode 100644 index 00000000000..44f05876cf2 --- /dev/null +++ b/text/0000-drop-types-in-const.md @@ -0,0 +1,40 @@ +- 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 `const`/`static` items, as long as the destructor is never run during `const` evaluation. + +# 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 trequired 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 +[design]: #detailed-design + +- Remove the check for `Drop` types in constant expressions. +- Add an error lint ensuring that `Drop` types are not dropped in a constant expression + - This includes when another field is moved out of a struct/tuple, and unused arguments in constant functions. + +# Drawbacks +[drawbacks]: #drawbacks + +Destructors do not run on `static` items (by design), so this can lead to unexpected behavior when a side-effecting type is stored in a `static` (e.g. a RAII temporary folder handle). However, this can already happen using the `lazy_static` crate, or with `Option` (which bypasses the existing checks). + +# Alternatives +[alternatives]: #alternatives + +Existing workarounds are based on storing `Option`, and initialising it to `Some` upon first access. These solutions work, but require runtime intialisation and incur a checking overhead on subsequent accesses. + +# Unresolved questions +[unresolved]: #unresolved-questions + +- TBD From c886a0aed5e912d731d359876b937903e666456c Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 1 Jan 2016 11:41:03 +0800 Subject: [PATCH 2/7] Update alternatives (UnsafeCell trick is a "bug", lazy_static uses raw pointers on stable) --- text/0000-drop-types-in-const.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/text/0000-drop-types-in-const.md b/text/0000-drop-types-in-const.md index 44f05876cf2..be6bdd6de6a 100644 --- a/text/0000-drop-types-in-const.md +++ b/text/0000-drop-types-in-const.md @@ -32,7 +32,10 @@ Destructors do not run on `static` items (by design), so this can lead to unexpe # Alternatives [alternatives]: #alternatives -Existing workarounds are based on storing `Option`, and initialising it to `Some` upon first access. These solutions work, but require runtime intialisation and incur a checking overhead on subsequent accesses. +- 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>` 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 From d400320c7dd63ce2aec827c60b0fba0a3960c9f8 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 1 Jan 2016 12:02:16 +0800 Subject: [PATCH 3/7] Replace detailed design with @eddyb's comments from rust-lang/rust#30667 --- text/0000-drop-types-in-const.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/text/0000-drop-types-in-const.md b/text/0000-drop-types-in-const.md index be6bdd6de6a..08c8a6ce85f 100644 --- a/text/0000-drop-types-in-const.md +++ b/text/0000-drop-types-in-const.md @@ -20,14 +20,17 @@ runtime-initialisation for global variables. # Detailed design [design]: #detailed-design -- Remove the check for `Drop` types in constant expressions. -- Add an error lint ensuring that `Drop` types are not dropped in a constant expression - - This includes when another field is moved out of a struct/tuple, and unused arguments in constant functions. + +- allow destructors in statics + - optionally warn about the "potential leak" +- allow instantiating structures that impl Drop in constant expressions +- prevent const items from holding values with destructors, but allow const fn to return them +- disallow constant expressions which would result in the Drop impl getting called, where they not in a constant context # Drawbacks [drawbacks]: #drawbacks -Destructors do not run on `static` items (by design), so this can lead to unexpected behavior when a side-effecting type is stored in a `static` (e.g. a RAII temporary folder handle). However, this can already happen using the `lazy_static` crate, or with `Option` (which bypasses the existing checks). +Destructors do not run on `static` items (by design), so this can lead to unexpected behavior when a side-effecting type is stored in a `static` (e.g. a RAII temporary folder handle). However, this can already happen using the `lazy_static` crate. # Alternatives [alternatives]: #alternatives From afea13ff8ec516c84ec34de968b5546db7f04fab Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 1 Jan 2016 12:24:43 +0800 Subject: [PATCH 4/7] Expand detailed design --- text/0000-drop-types-in-const.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/text/0000-drop-types-in-const.md b/text/0000-drop-types-in-const.md index 08c8a6ce85f..a96cbbb708b 100644 --- a/text/0000-drop-types-in-const.md +++ b/text/0000-drop-types-in-const.md @@ -6,7 +6,7 @@ # Summary [summary]: #summary -Allow types with destructors to be used in `const`/`static` items, as long as the destructor is never run during `const` evaluation. +Allow types with destructors to be used in `static` items and in `cosnt` functions, as long as the destructor never needs to run in const context. # Motivation [motivation]: #motivation @@ -20,17 +20,17 @@ runtime-initialisation for global variables. # Detailed design [design]: #detailed-design - -- allow destructors in statics - - optionally warn about the "potential leak" -- allow instantiating structures that impl Drop in constant expressions -- prevent const items from holding values with destructors, but allow const fn to return them -- disallow constant expressions which would result in the Drop impl getting called, where they not in a constant context +- 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 wth destructors. +- Disallow constant expressions which would result in the destructor being called (if the code were run at runtime). # Drawbacks [drawbacks]: #drawbacks -Destructors do not run on `static` items (by design), so this can lead to unexpected behavior when a side-effecting type is stored in a `static` (e.g. a RAII temporary folder handle). However, this can already happen using the `lazy_static` crate. +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. # Alternatives [alternatives]: #alternatives From a778e876e6514ba7ae37da330594a8b6c27a7fd7 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 1 Jan 2016 18:37:50 +0800 Subject: [PATCH 5/7] Add some examples --- text/0000-drop-types-in-const.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/text/0000-drop-types-in-const.md b/text/0000-drop-types-in-const.md index a96cbbb708b..60f9434d212 100644 --- a/text/0000-drop-types-in-const.md +++ b/text/0000-drop-types-in-const.md @@ -27,6 +27,28 @@ runtime-initialisation for global variables. - Allow `const fn` to return types wth 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 >> = RwLock::new( Vec::new() ); +``` + +Disallowed code +```rust +static VAL: usize = (Vec::::new(), 0).1; // The `Vec` would be dropped +const EMPTY_BYTE_VEC: Vec = Vec::new(); // `const` items can't have destructors + +const fn sample(_v: Vec) -> usize { + 0 // Discards the input vector, dropping it +} +``` + # Drawbacks [drawbacks]: #drawbacks From 1c9c699e958ef89509f021c8f3b826aaccd5b9f8 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 1 Jan 2016 21:44:05 +0800 Subject: [PATCH 6/7] Fix spelling errors --- text/0000-drop-types-in-const.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/text/0000-drop-types-in-const.md b/text/0000-drop-types-in-const.md index 60f9434d212..1db09dfa45d 100644 --- a/text/0000-drop-types-in-const.md +++ b/text/0000-drop-types-in-const.md @@ -6,13 +6,13 @@ # Summary [summary]: #summary -Allow types with destructors to be used in `static` items and in `cosnt` functions, as long as the destructor never needs to run in const context. +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 trequired to be a hard error. +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. @@ -24,7 +24,7 @@ runtime-initialisation for global variables. - (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 wth 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 From ccd4a78198d558810befcd44eb1282b80dbfeb9a Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 1 Jan 2016 22:19:26 +0800 Subject: [PATCH 7/7] Clarify collection types with non-allocating constructors, note that destructors will never run, acknowledge `.dtors` as alternative --- text/0000-drop-types-in-const.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/text/0000-drop-types-in-const.md b/text/0000-drop-types-in-const.md index 1db09dfa45d..92f79a19e7b 100644 --- a/text/0000-drop-types-in-const.md +++ b/text/0000-drop-types-in-const.md @@ -11,8 +11,8 @@ Allow types with destructors to be used in `static` items and in `const` functio # 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. +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 +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 runtime-initialisation for global variables. @@ -21,6 +21,7 @@ runtime-initialisation for global variables. [design]: #detailed-design - Lift the restriction on types with destructors being used in statics. + - `static`s containing Drop-types will not run the destructor upon program/thread exit. - (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. @@ -59,8 +60,9 @@ Destructors do not run on `static` items (by design), so this can lead to unexpe - 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>` can be used to remove the dynamic allocation. - -Both of these alternatives require runtime initialisation, and incur a checking overhead on subsequent accesses. + - Both of these alternatives require runtime initialisation, and incur a checking overhead on subsequent accesses. +- Leaking of objects could be addressed by using C++-style `.dtors` support + - This is undesirable, as it introduces confusion around destructor execution order. # Unresolved questions [unresolved]: #unresolved-questions