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

&mut T during the evaluation of a const/static initializer #16

Open
oli-obk opened this issue Oct 26, 2018 · 7 comments
Open

&mut T during the evaluation of a const/static initializer #16

oli-obk opened this issue Oct 26, 2018 · 7 comments

Comments

@oli-obk
Copy link
Contributor

oli-obk commented Oct 26, 2018

While is very important to not have static or const items of such types, during the evaluation of a static or const item we might want to work with intermediate values of this type.

E.g.

const FOO: usize = {
    let mut x = [5, 6, 7];
    x.swap(0, 1);
    x[0] // should be `6`
};

seems totally reasonable.

@oli-obk oli-obk changed the title &mut T and &NonFreezeType during the evaluation of a const/static initializer &mut T during the evaluation of a const/static initializer Oct 26, 2018
@RalfJung
Copy link
Member

So what about constants of type MaybeInitialized<&mut T>?

@oli-obk
Copy link
Contributor Author

oli-obk commented Oct 30, 2018

That's fine, even on nightly: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2015&gist=a9a11a688079f6535f8e7e548cdbcd3a

Const eval will error out if you leak a local and you can't promote a mutable reference to something other than []

@RalfJung
Copy link
Member

RalfJung commented Oct 30, 2018

Hm. I am still confused by what exactly the guarantee is that we need.

So it is okay to have &mut below a union, but not below a tuple? struct? enum? What if someone calls into_inner on that MaybeInitialized<&mut T>?

Const eval will error out if you leak a local

That's because StorageDead killed the local, right? Does it do that reliably? And didn't we hope to lift that restriction some day?


I see two parts to this:

  • First make sure that if someone somehow manages to get an &mut, writing to it will fail. To this end, we have to set the mutability of the allocations appropriately during interning. Currently, what we do is somewhat odd: First of all, we don't actually make sure here that all const are Mutability::Immutable (bug?), and secondly, we use the same mutability for the static/const itself and anything it references that hasn't been interned already (i.e., anything new, added by this static/const). The latter part cannot be right. I think right now it would be correct to make everything that gets referenced immutable because the only legal way for it to refer to something mutable is to reference another static, right?
  • If we can rely on allocation mutability to be set correctly, it seems sufficient to ensure that we never have an &mut to an immutable allocation. Validity could perform that check. Is that sufficient?

@RalfJung
Copy link
Member

Also, shouldn't this be tracked in /~https://github.com/rust-rfcs/const-eval/?

@oli-obk
Copy link
Contributor Author

oli-obk commented Oct 31, 2018

we are in rust-rfcs!? 🤣

the only legal way for it to refer to something mutable is to reference another static, right?

Not from within another static/const. If an immutable (and thus safe to access) static contained a mutable reference to another static, then you'd be able to "safely" obtain two mutable references to the same static, which is obviously wrong.

That's because StorageDead killed the local, right? Does it do that reliably? And didn't we hope to lift that restriction some day?

Yes, Yes, No

I don't see how we could lift that and how that would be sound.

Making this a validation guarantee does have some nice properties, but fails out of the same reasons that the freeze and needs drop checks can't be part of validation. Associated constants would end up causing monomorphization time errors.

@RalfJung
Copy link
Member

we are in rust-rfcs!? rofl

Oh, eh... look, a three-headed monkey! 🐵 🐵 🐵

@RalfJung
Copy link
Member

Not from within another static/const. If an immutable (and thus safe to access) static contained a mutable reference to another static, then you'd be able to "safely" obtain two mutable references to the same static, which is obviously wrong.

Ah that's your concern. Yeah you should only get shared refs there. So without interior mutability, there wouldn't even be a problem...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants