Description
// foo.rs
extern mod bar;
fn main() {
unsafe {
bar::test(&bar::argh);
}
}
// bar.rs
use std::cast;
static mut argh: int = 1;
pub unsafe fn test(a: &'static int) {
let a: uint = cast::transmute(a);
let b: uint = cast::transmute(&argh);
assert_eq!(a, b);
}
Currently it appears that whenever a static value is referenced from another crate, a local translation is made and then the address of that is taken instead. This means that every static referenced from another crate will be re-translated into the current crate, thereby giving it a different address than ones in other crates.
For optimizations, I can see where this is nice to know the value of the static, but this breaks any usage of cross-crate TLS apis. Namely, this prevents conditions from working cross-crate. I can think of two fixes for this:
- All addresses of external statics are resolved through whatever LLVM's equivalent of
extern
references are. - Statics can be tagged with some
#[]
attribute meaning that their address is significant or that they basically shouldn't be re-translated into other crates.
I would prefer option 1 over option 2, but I'm not sure if performance for optimizations would suffer as a result. I think that the fix might go into trans_addr_of
, but I'm not sure where the best place for this would be.
cc @graydon (you were interested in cross-crate conditions not working)