Skip to content

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

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

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
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

3 participants