Skip to content

break in consteval has strange const promotion behavior #145528

@theemathas

Description

@theemathas

I don't know what the correct behavior is. However, this combination of behaviors with these variations in the code seem rather inconsistent.

The below code compiles, seemingly due to const promotion or temporary lifetime extension:

#![allow(unreachable_code, unused)]

const A: () = {
    let _x: &i32 = 'a: {
        break 'a &one();
        panic!()
    };
};

const fn one() -> i32 {
    1
}

Adding an irrelevant if true {} makes it not compile, even without the &'static annotation:

#![allow(unreachable_code, unused)]

const A: () = {
    let _x = 'a: {
        if true {}
        break 'a &one();
        panic!()
    };
};

const fn one() -> i32 {
    1
}
error[E0716]: temporary value dropped while borrowed
 --> src/lib.rs:6:19
  |
4 |     let _x = 'a: {
  |         -- borrow later stored here
5 |         if true { }
6 |         break 'a &one();
  |                   ^^^^^- temporary value is freed at the end of this statement
  |                   |
  |                   creates a temporary value which is freed while still in use
  |
  = note: consider using a `let` binding to create a longer lived value

For more information about this error, try `rustc --explain E0716`.
error: could not compile `playground` (lib) due to 1 previous error

Adding a break inside the condition makes the error blame the panic:

#![allow(unreachable_code, unused)]

const A: () = {
    let _x = 'a: {
        if true {
            break 'a &1;
        }
        break 'a &one();
        panic!()
    };
};

const fn one() -> i32 {
    1
}
error[E0716]: temporary value dropped while borrowed
 --> src/lib.rs:8:19
  |
8 |         break 'a &one();
  |                   ^^^^^- temporary value is freed at the end of this statement
  |                   |
  |                   creates a temporary value which is freed while still in use
9 |         panic!()
  |         -------- borrow later used here
  |
  = note: consider using a `let` binding to create a longer lived value

For more information about this error, try `rustc --explain E0716`.
error: could not compile `playground` (lib) due to 1 previous error

Putting the initial code inside a fn instead of a const makes it not compile, even without the &'static annotation:

#![allow(unreachable_code, unused)]

fn foo() {
    let _x: &i32 = 'a: {
        break 'a &one();
        panic!()
    };
}

const fn one() -> i32 {
    1
}
error[E0716]: temporary value dropped while borrowed
 --> src/lib.rs:5:19
  |
4 |     let _x: &i32 = 'a: {
  |         -- borrow later stored here
5 |         break 'a &one();
  |                   ^^^^^- temporary value is freed at the end of this statement
  |                   |
  |                   creates a temporary value which is freed while still in use
  |
  = note: consider using a `let` binding to create a longer lived value

For more information about this error, try `rustc --explain E0716`.
error: could not compile `playground` (lib) due to 1 previous error

Putting the initial code inside if false makes it not compile, even without the &'static annotation:

#![allow(unreachable_code, unused)]

const A: () = if false {
    let _x: &i32 = 'a: {
        break 'a &one();
        panic!()
    };
};

const fn one() -> i32 {
    1
}
playground)
error[E0716]: temporary value dropped while borrowed
 --> src/lib.rs:5:19
  |
4 |     let _x: &i32 = 'a: {
  |         -- borrow later stored here
5 |         break 'a &one();
  |                   ^^^^^- temporary value is freed at the end of this statement
  |                   |
  |                   creates a temporary value which is freed while still in use
  |
  = note: consider using a `let` binding to create a longer lived value

For more information about this error, try `rustc --explain E0716`.
error: could not compile `playground` (lib) due to 1 previous error

@rustbot labels +A-const-eval

CC @traviscross

Meta

All code snippets tested on the playground with version 1.89.0.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)C-discussionCategory: Discussion or questions that doesn't represent real issues.T-langRelevant to the language team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions