Allow types with destructors in static variables #1111

Closed
Kimundi opened this Issue May 9, 2015 · 12 comments

Comments

Projects
None yet
@Kimundi
Member

Kimundi commented May 9, 2015

Currently, Rust forbids statics from containing types with destructors:

struct Foo; 
impl Drop for Foo { 
    fn drop(&mut self) {} 
} 
static FOO: Foo = Foo;
error: statics are not allowed to have destructors

This was historically motivated by the question of when to run the destructor:

  • There where worries about supporting life before/after main() for, eg, static variables due to them having historically caused trouble in, eg, C++ code bases.
  • Leaking the destructor was also for the most time not known to be a feasible option due to leaking possibly being bad.

The conservative choice was to forbid such types outright until a decision could be reached.

However, a lot has happened since then:

  • Rusts runtime basically disappeared, with no noteworthy amount of code running before/after main() anymore.
  • With #1066 accepted the language now defines leaking as being safe and allows it in certain circumstances.

Informally, language semantic and idiomatic code now shifted into this position:

  • No user code will run before/after main(), and all initialization/deinitialization needs to happen in it.
  • Leaking destructors is ok if the object lives infinitely long (RC circle, Box<T> -> &'static T)

In keeping with that trend, the language semantic should be changed as follows:

  • It is allowed to store a type with a destructor in a static variable.
  • Values in static variables will never have their destructors run automatically.

The benefit would be more freedom around static variables.

As a concrete use case, this change would allow lazy_static to work without requiring a heap allocation. (It currently uses a raw pointer to a heap allocation in a mutable static to get around the destructor issue)

@scialex

This comment has been minimized.

Show comment
Hide comment
@scialex

scialex May 10, 2015

Another place this would be useful is os Dev. See http://scialex.github.io/reenix.pdf section 3.2.3

Often we have statics that hold global state that would make most sense as maps and the like.

scialex commented May 10, 2015

Another place this would be useful is os Dev. See http://scialex.github.io/reenix.pdf section 3.2.3

Often we have statics that hold global state that would make most sense as maps and the like.

@arielb1

This comment has been minimized.

Show comment
Hide comment
@arielb1

arielb1 May 10, 2015

Contributor

+1 for this. This shouldn't have soundness implications – you can already get an essentially-equivalent behaviour by rooting your dtor-ey struct in main and never returning (exiting by signal/_exit/exit), which is not particularly non-standard for daemons – but this requires threading a lifetime through everything, which is very ugly.

Contributor

arielb1 commented May 10, 2015

+1 for this. This shouldn't have soundness implications – you can already get an essentially-equivalent behaviour by rooting your dtor-ey struct in main and never returning (exiting by signal/_exit/exit), which is not particularly non-standard for daemons – but this requires threading a lifetime through everything, which is very ugly.

@pythonesque

This comment has been minimized.

Show comment
Hide comment
@pythonesque

pythonesque May 11, 2015

Contributor

I am generally in favor. My only hesitation is that I vaguely remember finding a way that I would have been able to violate memory safety by abusing the fact that thread locals are 'static if static types with destructors were legal, but I can't actually remember how I was planning to do it, and I may have been mistaken that it was possible.

Contributor

pythonesque commented May 11, 2015

I am generally in favor. My only hesitation is that I vaguely remember finding a way that I would have been able to violate memory safety by abusing the fact that thread locals are 'static if static types with destructors were legal, but I can't actually remember how I was planning to do it, and I may have been mistaken that it was possible.

@arielb1

This comment has been minimized.

Show comment
Hide comment
@arielb1

arielb1 May 12, 2015

Contributor

@pythonesque

'static thread-locals are not sound anyway in the presence of scoped threads. We essentially need some form of 'thisthread to make them sound.

Contributor

arielb1 commented May 12, 2015

@pythonesque

'static thread-locals are not sound anyway in the presence of scoped threads. We essentially need some form of 'thisthread to make them sound.

@rasendubi

This comment has been minimized.

Show comment
Hide comment
@rasendubi

rasendubi Jan 15, 2016

Any update on this?

Any update on this?

@golddranks

This comment has been minimized.

Show comment
Hide comment
@golddranks

golddranks Jan 15, 2016

#913 Maybe related.

#913 Maybe related.

@SimonSapin

This comment has been minimized.

Show comment
Hide comment
@SimonSapin

SimonSapin Mar 8, 2016

Contributor

CC @nikomatsakis, could the lang team discuss this and decide? Thanks!

(I’m in favor.)

Contributor

SimonSapin commented Mar 8, 2016

CC @nikomatsakis, could the lang team discuss this and decide? Thanks!

(I’m in favor.)

@thepowersgang

This comment has been minimized.

Show comment
Hide comment
@thepowersgang

thepowersgang Mar 8, 2016

Contributor

#1440 is a draft RFC allowing this, but it may need major revision or rewriting.

Contributor

thepowersgang commented Mar 8, 2016

#1440 is a draft RFC allowing this, but it may need major revision or rewriting.

@nikomatsakis

This comment has been minimized.

Show comment
Hide comment
@nikomatsakis

nikomatsakis Mar 9, 2016

Contributor

On Tue, Mar 08, 2016 at 06:16:42AM -0800, Simon Sapin wrote:

CC @nikomatsakis, could the lang team discuss this and decide? Thanks!

I'm roughly in favor. I'll try to take a look at the pending RFC.

Contributor

nikomatsakis commented Mar 9, 2016

On Tue, Mar 08, 2016 at 06:16:42AM -0800, Simon Sapin wrote:

CC @nikomatsakis, could the lang team discuss this and decide? Thanks!

I'm roughly in favor. I'll try to take a look at the pending RFC.

@nrc nrc added the T-lang label Aug 30, 2016

@briansmith

This comment has been minimized.

Show comment
Hide comment
@briansmith

briansmith Sep 15, 2016

What is the difference between #1111, #1440, and #913? Since #1440 is merged, can the other two things be closed? If not, why not?

What is the difference between #1111, #1440, and #913? Since #1440 is merged, can the other two things be closed? If not, why not?

@Kimundi

This comment has been minimized.

Show comment
Hide comment
@Kimundi

Kimundi Nov 16, 2016

Member

Indeed, seems like this and #913 can be closed now. I'll update lazy_static to rely on #1440 as a test, then will close.

Member

Kimundi commented Nov 16, 2016

Indeed, seems like this and #913 can be closed now. I'll update lazy_static to rely on #1440 as a test, then will close.

@Kimundi

This comment has been minimized.

Show comment
Hide comment
@Kimundi

Kimundi Nov 19, 2016

Member

Closing after having verified that everything works as expected.

Member

Kimundi commented Nov 19, 2016

Closing after having verified that everything works as expected.

@Kimundi Kimundi closed this Nov 19, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment