Skip to content

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

Closed
@Rua

Description

@Rua
Contributor

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.

Activity

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[/+] on May 11, 2021
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[/+] on May 11, 2021
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[/+] on May 11, 2021
memoryruins

memoryruins commented on May 11, 2021

@memoryruins
Contributor

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

memoryruins commented on May 15, 2021

@memoryruins
Contributor

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

RalfJung

RalfJung commented on May 15, 2021

@RalfJung
Member

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

RalfJung commented on Jul 7, 2021

@RalfJung
Member

Closing as intended behavior per this RFC.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @RalfJung@Rua@memoryruins

        Issue actions

          Can't promote temporary to static when a `const fn` is involved · Issue #85181 · rust-lang/rust