Description
Let's say you're a library author. You just published the following library file under the name libbar
:
// bar.rs
pub fn foo<T>() -> int {
static a: int = 4;
return a;
}
Some innocent programmer then comes along and uses this file. They write the following program
// foo.rs
extern mod bar;
fn main() {
bar::foo::<int>();
}
Being a responsible library developer, you then realize that your library has a security flaw, so you update it to:
// updated bar.rs
fn fix_the_bug() {}
pub fn foo<T>() -> int {
static a: int = 4;
return a;
}
You realize that this change is ABI-compatible with your previous library version, so being a responsible library developer, you push out an updated version of your new library.
As a responsible application developer, the client using your library then updates their copy, only to result in the following terrible-ness. (this shell session assumes that I'm both the library and application developer).
// let's compile libbar for the first time
$ ./x86_64-apple-darwin/stage2/bin/rustc --lib bar.rs
warning: missing crate link meta `name`, using `bar` as default
warning: missing crate link meta `vers`, using `0.0` as default
warning: no debug symbols in executable (-arch x86_64)
// Now let's compile our application, link it against libbar, and run it
$ ./x86_64-apple-darwin/stage2/bin/rustc foo.rs -L.
warning: no debug symbols in executable (-arch x86_64)
$ ./foo
// Awesome! now let's update libbar (with the bugfix), and recompile
$ ./x86_64-apple-darwin/stage2/bin/rustc --lib bar.rs
warning: missing crate link meta `name`, using `bar` as default
warning: missing crate link meta `vers`, using `0.0` as default
warning: no debug symbols in executable (-arch x86_64)
// The library didn't move, and it didn't change name, we shouldn't
// have to recompile foo here.
$ ./foo
dyld: Symbol not found: __ZN3foo1a19hff345045bc2f6a3eaj4v0.0E
Referenced from: /Users/alex/code/rust3/./foo
Expected in: /Users/alex/code/rust3/./libbar-15fb3a718ea23983-0.0.dylib
in /Users/alex/code/rust3/./foo
zsh: trace trap ./foo
The reason for this is that 1da4488 introduced the idea of a "pretty name" for statics which uses the node_id
as the "unique tidbit" of information for a static in order to guarantee that they all have different names. This is very undesirable, and this should definitely be fixed.
Nominating for production-ready, and possibly the priority tag.
All credit for finding this goes to @cmr's eagle eyes.