Closed
Description
See this playground code:
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.
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
[-]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[/+][-]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[/+][-]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[/+]memoryruins commentedon 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 likeconst { &Foo::new() }
.memoryruins commentedon May 15, 2021
To be clear, I think the behavior is intended to stay this way. cc @RalfJung
RalfJung commentedon 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 insidestatic
/const
bodies is astute, as demonstrated by this variant of your example:This is for backwards compatibility and because the concerns around promoting
const fn
that I mentioned above apply less insideconst
/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 commentedon Jul 7, 2021
Closing as intended behavior per this RFC.