#[linkage] does not propagate through generic functions
alexcrichton opened this issue · 3 comments
alexcrichton commented
For example:
// lib.rs
#![feature(linkage)]
pub fn foo<T>() -> *const () {
extern {
#[linkage = "extern_weak"]
static FOO: *const ();
}
FOO
}
// main.rs
extern crate lib;
fn main() {
lib::foo::<int>();
}
$ rustc lib.rs --crate-type rlib
$ rustc main.rs -L .
error: linking with `cc` failed: exit code: 1
note: cc '-Wl,--as-needed' '-m64' '-L' '/home/alex/code/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib' '-o' 'main' 'main.o' '-Wl,--whole-archive' '-lmorestack' '-Wl,--no-whole-archive' '-fno-lto' '-Wl,--gc-sections' '-pie' '-nodefaultlibs' '/home/alex/liblib.rlib' '/home/alex/code/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libnative-4e7c5e5c.rlib' '/home/alex/code/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-4e7c5e5c.rlib' '/home/alex/code/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libsync-4e7c5e5c.rlib' '/home/alex/code/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustrt-4e7c5e5c.rlib' '/home/alex/code/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcollections-4e7c5e5c.rlib' '/home/alex/code/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunicode-4e7c5e5c.rlib' '/home/alex/code/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-4e7c5e5c.rlib' '/home/alex/code/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/librand-4e7c5e5c.rlib' '/home/alex/code/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-4e7c5e5c.rlib' '/home/alex/code/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-4e7c5e5c.rlib' '-L' '.' '-L' '/home/alex/.rust' '-L' '/home/alex' '-Wl,--whole-archive' '-Wl,-Bstatic' '-Wl,--no-whole-archive' '-Wl,-Bdynamic' '-ldl' '-lpthread' '-lgcc_s' '-lpthread' '-lc' '-lm' '-lcompiler-rt'
note: main.o:main.0.rs:function foo::h6978205699166201756: error: undefined reference to 'FOO'
collect2: error: ld returned 1 exit status
error: aborting due to previous error
This can be a little more clearly seen with the IR generated for main:
; ModuleID = 'main.0.rs'
target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
@FOO = external global {}*
...
Note the lack of extern_weak
anywhere on FOO
.
steveklabnik commented
Triage: this is still true today, though int
needs to be updated to i32
, and there's now a warning about ()
not being a valid foreign type, which is irrelevant to this particular issue.
brson commented
@Mark-Simulacrum claims it repros still.
yodaldevoid commented
Updated test code:
// lib.rs
#![feature(linkage)]
pub fn foo<T>() -> *const() {
extern {
#[linkage = "extern_weak"]
static FOO: *const();
}
unsafe { FOO }
}
// main.rs
extern crate lib;
fn main() {
lib::foo::<i32>();
}
Still fails to compile with the same errors mentioned in the top post along with the irrelevant invalid foreign type warning mentioned by @steveklabnik.