Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

constant reference has unstable address acrosss compilation units. #72004

Open
moxian opened this issue May 8, 2020 · 1 comment
Open

constant reference has unstable address acrosss compilation units. #72004

moxian opened this issue May 8, 2020 · 1 comment
Labels
A-const-eval Area: Constant evaluation (MIR interpretation) A-docs Area: documentation for any part of the project, including the compiler, standard library, and tools C-bug Category: This is a bug.

Comments

@moxian
Copy link
Contributor

moxian commented May 8, 2020

Consider the following code, split across two crates:

//crate_b; lib.rs:
#![feature(const_fn)]

pub const fn give_ptr<T>(x: &T) -> *const T { x as *const T }
pub const MY_CONST: &'static i32 = &1;
pub const fn my_const_ptr() -> *const i32 { give_ptr(MY_CONST) }


//crate_a; depends on crate_b; main.rs:
fn main() {
    assert_eq!(crate_b::my_const_ptr(), crate_b::give_ptr(crate_b::MY_CONST));
    // thread 'main' panicked at 'assertion failed: `(left == right)`
    //   left: `0x13fe2b3d0`,
    //  right: `0x13fe2b300`', src\main.rs:3:5
}

This behavior is mildly surprising - effectively inlining a function changes the computation result.

The reference mentions a similar situation:

References to the same constant are not necessarily guaranteed to refer to the same memory address

however, as written, this is not applicable to the code above - there's only one reference to a constant, not multiple. It is the same reference to a constant that gets treated differently based on the compilation unit.

I understand that this is an incredibly niche situation, and likely no real code hits it.
I also understand that it's likely very hard to "fix" the "bug" (i.e. make assert_eq! above pass).
I think I'd be happy if the reference doc was simply adjusted instead (but have no suggestion on a better wording). I'm mildly concerned that even with better wording, the code might be obfuscated enough to the point where main() does not see any reference types while doing the inlining, yet still triggers the bug (but I couldn't craft such obfuscation myself).

@moxian moxian added the C-bug Category: This is a bug. label May 8, 2020
@RalfJung
Copy link
Member

RalfJung commented May 8, 2020

Cc @rust-lang/wg-const-eval

however, as written, this is not applicable to the code above - there's only one reference to a constant, not multiple.

The reference doesn't say "multiple". Each use of a const is basically equivalent to inlining the const definition at that place, except address identity might or might not be preserved. I would thus argue the reference text does apply to your code.

So, this is definitely behavior as intended (if you need stable addresses, use static).

We're open to suggestions for how to make the reference more clear on this. :)

@RalfJung RalfJung added A-const-eval Area: Constant evaluation (MIR interpretation) A-docs Area: documentation for any part of the project, including the compiler, standard library, and tools labels May 8, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-const-eval Area: Constant evaluation (MIR interpretation) A-docs Area: documentation for any part of the project, including the compiler, standard library, and tools C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

2 participants