-
Notifications
You must be signed in to change notification settings - Fork 13.8k
Description
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).