The old issue appears to be talking about symbol versioning in the context of a stable Rust ABI (the thing we'd need in order to ship librust-std.so.1
); whereas I understand OP to be asking for the smaller feature of symbol versioning on an exported C-compatible interface.
For LTO to work correctly, the compiler needs to know what the versioning directives mean; they can't just be emitted as opaque inline assembly directives. This means this feature request is going nowhere until LLVM grows support for something equivalent to GCC's __attribute__((symver))
(as far as I can tell LLVM currently doesn't have this, but I could have missed something).
Second, I think it will be more ergonomic to separate the version annotation from the exported-name annotation, and not make the programmer remember how many @
signs they need; perhaps something like
#[export_name = "foo", version = "LIBX_1.0"]
pub fn old_foo () {}
#[export_name = "foo", version = "LIBX_2.0", default_version]
pub fn new_foo () {}
or
#[export_name = ("foo", version = "LIBX_1.0")]
pub fn old_foo () {}
#[export_name = ("foo", version = "LIBX_2.0", default_version)]
pub fn new_foo () {}
And finally, if you need this feature, you are likely to also need to be able to assign multiple exported names (each with its own version) to a single item. This would be easier to accommodate with the syntax with the parentheses:
#[export_name = [
("foo", version = "LIBX_1.0"),
("foo", version = "LIBX_2.0", default),
("foobar", version = "LIBY_0.5") // an obsolete fork
]]
pub fn i_am_many_foos () {}
(If you're thinking YAGNI, I invite you to review the build process for libxcrypt, particularly the files lib/libcrypt.map.in
and lib/libcrypt.minver
and how they get turned into crypt-symbol-vers.h
.)