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

Can't promote temporary to static when a const fn is involved #85181

Closed
Rua opened this issue May 11, 2021 · 4 comments
Closed

Can't promote temporary to static when a const fn is involved #85181

Rua opened this issue May 11, 2021 · 4 comments
Labels
C-bug Category: This is a bug.

Comments

@Rua
Copy link
Contributor

Rua commented May 11, 2021

See this playground code:

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=c21ca661aa56e4594e46510acd21c630

In the case of _bar, the code gives no errors. The compiler is able to promote the temporary into a static. But for _baz, which calls a const fn, the compiler fails to do this, and complains of a temporary being dropped. It is, however, able to do so for _STATIC, which is explicitly declared as a static variable.

Of course, it shouldn't be dropping the temporary here, but promote it to static just like the first line.

@Rua Rua added the C-bug Category: This is a bug. label May 11, 2021
@Rua Rua changed the title Compiler can't promote temporary array to static slice when a const fn is involved Can't promote temporary array to static slice when a const fn is involved May 11, 2021
@Rua Rua changed the title Can't promote temporary array to static slice when a const fn is involved Can't promote temporary to static slice when a const fn is involved May 11, 2021
@Rua Rua changed the title Can't promote temporary to static slice when a const fn is involved Can't promote temporary to static when a const fn is involved May 11, 2021
@memoryruins
Copy link
Contributor

memoryruins commented May 11, 2021

Arbitrary const fn are not implicitly promoted unless if inside of a const context. inline_const may allow const contexts to be created succinctly like const { &Foo::new() }.

@memoryruins
Copy link
Contributor

To be clear, I think the behavior is intended to stay this way. cc @RalfJung

@RalfJung
Copy link
Member

RalfJung commented May 15, 2021

Yes, this is intended. Promoting const fn in your _baz would cause all sorts of problems, see rust-lang/const-eval#19 and this RFC. Note that your _STATIC does not benefit from promotion, even unpromotable calls like &Vec::new() would work there -- see this document for details, in particular the section on the "enclosing scope" rule.

However, your observation that const fn get promoted inside static/const bodies is astute, as demonstrated by this variant of your example:

    static _STATIC2: &Foo = {
        let x = &Foo::new();
        x
    };

This is for backwards compatibility and because the concerns around promoting const fn that I mentioned above apply less inside const/static bodies. This is also currently being discussed in the RFC's tracking issue #80619.

So, the summary is that _baz must not be accepted (and it never was -- we did some breaking changes around promotion earlier this year, but this code was never allowed). We could, for consistency, also reject _STATIC2 and even _STATIC, but (a) that would be massively backwards-incompatible, and (b) one could argue that it is good to accept more code where possible, even if that introduced surprising distinctions like the one you are encountering here.

@RalfJung
Copy link
Member

RalfJung commented Jul 7, 2021

Closing as intended behavior per this RFC.

@RalfJung RalfJung closed this as completed Jul 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

3 participants