Strange behavior of user defined Struct's const raw pointer

Today, I wrote some rust code exercise, learning about const knowledge, every thing goes well, except the const raw pointer.

Below is the code snippet

const FOO_PTR: *const FOO  = &FOO {} as *const FOO;
struct FOO {}
fn main() {
}
impl Drop for FOO {
    fn drop(&mut self) {
        println!("FOO drop");
    }
}

compile it, and I got
error: untyped pointers are not allowed in constant
--> src\main.rs:11:1
|
11 | const FOO_PTR: *const FOO = &FOO {} as *const FOO;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If I remove the Drop implement code, it compiles success.

Does anyone know what's going there?

You can't have Drop in consts because const-eval can't run arbitrary code.

2 Likes

@RustyYato does the rule only apply in const raw pointer?
I defined FOO in this way and has Drop impl, compiles fine
const FOO: FOO = FOO {}

I don't understand why you get that error, but you probably want static instead.

static FOO: Foo = Foo {};

This FOO will never be dropped.

Every time you use that FOO in an expression, the compiler will create a new Foo that will be dropped at the end of the enclosing scope. So writing this

fn main() {
    FOO;
    FOO;
}

will print the drop message twice.

It may be confusing if you're used to a language like C or C++ because those languages use const to mean "readonly"; it's a modifier on the type of an otherwise normal variable. Rust's const is more closely related to C++'s constexpr.

2 Likes

@trentj, thanks for so details explanation

No it applies in any const context. Aside from const values it's likely only const fns at this moment.

1 Like