Stream: t-compiler/const-eval

Topic: rvalue promotion


Jake Goulding (Jan 20 2019 at 16:49, on Zulip):

Should we expect rvalue promotion to kick in for const fn at some point?

struct Foo(i32);
impl Foo {
    const fn new() -> Self {
        Foo(42)
    }
}

fn example() -> &'static Foo {
    &Foo::new()
}
error[E0515]: cannot return reference to temporary value
 --> src/lib.rs:9:5
  |
9 |     &Foo::new()
  |     ^----------
  |     ||
  |     |temporary value created here
  |     returns a reference to data owned by the current function
Jake Goulding (Jan 20 2019 at 16:49, on Zulip):

Whereas these work:

fn example() -> &'static Foo {
    static A: Foo = Foo::new();
    &A
}
fn example() -> &'static Foo {
    &Foo(42)
}
Jake Goulding (Jan 20 2019 at 16:52, on Zulip):

/cc @Oli

Matthew Jasper (Jan 20 2019 at 16:53, on Zulip):

I think the answer is no: #53851

Jake Goulding (Jan 20 2019 at 16:59, on Zulip):

@Matthew Jasper ah, thank you!

Jake Goulding (Jan 20 2019 at 17:00, on Zulip):

Although I read it a bit differently: more like "we don't know what we want now, so be conservative". Maybe once we know more, we can unlock it.

oli (Jan 21 2019 at 08:11, on Zulip):

I have formulated a "no" here: https://github.com/rust-rfcs/const-eval/issues/19

Jake Goulding (Jan 21 2019 at 14:48, on Zulip):

This is not what I wanted. Y u do this.

Jake Goulding (Jan 21 2019 at 14:49, on Zulip):

(I mean, I'm gonna read it, and I'm sure there are good reasons)

oli (Jan 21 2019 at 15:03, on Zulip):

I'm fine with it if we invent sth like &const { Foo::new() } blocks

oli (Jan 21 2019 at 15:03, on Zulip):

or possibly even &static { Foo::new() }, which fits the semantics more

rkruppe (Jan 21 2019 at 15:04, on Zulip):

I was about to say that

oli (Jan 21 2019 at 15:05, on Zulip):

the static part or the explicit blocks part?

rkruppe (Jan 21 2019 at 15:06, on Zulip):

The static part. The const block part is clear IMO -- it's an anonymous constant, so it's just like const X: _ = Foo::new(); &X which is distinct from promotion.

rkruppe (Jan 21 2019 at 15:07, on Zulip):

Well, it's not promotion of the Foo::new() call at least

rkruppe (Jan 21 2019 at 15:08, on Zulip):

Hm, but it works in every case where opt-in promotion would work, so there's really no need to introduce static {}, is there?

oli (Jan 21 2019 at 15:15, on Zulip):

The rationale for not allowing &Foo::new() is in the link further up. But yes, trivial cases like &SOME_CONST should not require &static{SOME_CONST}

rkruppe (Jan 21 2019 at 15:17, on Zulip):

I know the rationale, I mean that whenever "opt-in promotion" would work, so would &const { <expr> } under the usual proposed meaning of the block (anonymous constant). Hence, no need to actually introduce "opt-in promotion", it's subsumed by anonymous constants.

rkruppe (Jan 21 2019 at 15:17, on Zulip):

Despite anonymous constants being, well, constants rather than statics.

oli (Jan 21 2019 at 15:22, on Zulip):

We can't just desugar at the AST level, since we don't have constants that infer their types (and I don't think we should go down that avenue)

oli (Jan 21 2019 at 15:22, on Zulip):

But we already have anonymous constants in the compiler. Array lengths and enum discriminant inititalizers are both anonymous constants

Jake Goulding (Jan 21 2019 at 18:50, on Zulip):

&static { Foo::new() } — feels too close to the generator (?) syntax of static || {}

Taylor Cramer (Jan 21 2019 at 18:56, on Zulip):

That generator syntax is entirely temporary

Taylor Cramer (Jan 21 2019 at 18:56, on Zulip):

It's not meant to stick around :)

Jake Goulding (Jan 22 2019 at 02:06, on Zulip):

oh? will something need to replace it?

Patrrick (Jan 22 2019 at 10:04, on Zulip):

Test

Patrrick (Jan 22 2019 at 10:05, on Zulip):

&static { Foo::new() } — feels too close to the generator (?) syntax of static || {}

This is a reply

Last update: Nov 15 2019 at 20:05UTC