Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Ah yes, that RFC is roughly what I had in mind, thanks.

I believe that it's safe to promote through an if, although obviously not through a general loop.



Yes, I agree that it should be safe, I've softened my original text. However, it would require dynamically tracking if the destructor needs to be run, and there's currently discussion[1] about Rust possibly moving to a static model, for the highest performance.

[1]: https://github.com/rust-lang/rfcs/pull/210


Consider this:

On a two-way if statement, then a given storage location is either set on zero, one or both branches. If it is set on neither branch then the if statement is irrelevant and can be ignored. If it is set on one branch, then either it had an original value and hence can be treated as being set on both branches, or it must be destroyed within the branch of the if (no null pointers - think about it until it is clear that the type system guarantees this). Hence we are only interested in cases which are isomorphic with the location being set on both branches.

We can treat this as a phi node following the if: there is one output value, which has been created in one of two different ways. In this case we don't know statically which value has been constructed, but we do know statically how and when to destroy it regardless of which one we get, because both branches have the same type and storage location. We don't actually need to know where it came from.

Any obvious problems? I think it works...


It doesn't work, the &str could come from completely different types in the two branches.

I.e. one branch could be created by .as_slice() on a String, the other could be created by referencing a global, e.g.

  let s = if cond {
      let some_string = create_it();
      some_string.as_slice()
  } else {
      "literals are always-valid &str's"
  };
`some_string`s destructor should only be run if the first branch was taken.


I'm not sure that this particular example can ever use some_string outside the if without hitting a type error, but I see what you mean.

That seems like a reasonable case to raise a type error. That defines the cases quite neatly: if it's temporary on both branches then it can work, and if it has different lifetimes then the values can't be merged and should be rejected. If the programmer really meant for this to work then they need to copy the global, and copies should be written explicitly.


There's no type error at all, we're talking about delaying the destruction of some_string so that the `s` (which is a &str) is valid outside the if. The string literal is a &str with a infinite lifetime, and so can of course be safely restricted to have the same lifetime as the other branch (done implicitly).

However, it's easily possible to have the &str come from temporaries of different types in the two branches. This would restrict the static destruction case to only working through an `if` when the "parent" values have exactly the same types; which doesnt seem nearly as valuable and possibly not worth the effort.


Couldn't the compiler get around that by introducing a boolean variable that is set depending on the branch of the if statement taken, that it checks before running the destructor?

Although this starts getting really messy.


Yes, that's exactly how it would be handled, but it's then dynamic destruction, not static.


Can you elaborate? I fail to see why this is dynamic - it still determines at compile time if/when to run destructors. I was under the impression that dynamic destruction was when you determine when to run destructors at runtime. Garbage collectors or reference counting, in other words.


It is dynamic because it is not known if the destructor call is executed at compile time. I'm using the terminology from RFC PR #210 that I linked above.


Oh, ok.

On a related note, the approach I mentioned is actually mentioned in that RFC PR:

> Store drop-flags for fragments of state on stack out-of-band


Yes, correct, that's what "dynamic destruction" is referring to.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: