You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Well, without #[no_mangle] I was not able to find it in the generated library.
Do you see foo1 in the generated library without using #[no_mangle]?
Only symbols with #[no_mangle] are guaranteed to be in the generated code for a library.
But without using #[no_mangle], I can get foo2, but not foo1. It looks like it is not the lack of #[no_mangle] on foo1 that is causing it to be ignored when building the library, but rather the fact that it uses is_some(). Somehow using is_some() causes foo1 to be lost somewhere in the MIR -> LLVM IR process.
I wrote the PR that caused this change. The function is not lost. It is in the not-yet-lowered part of the rlib because the compiler has deduced that the function should be made eligible for cross-crate inlining, and rustc implements cross-crate-inlining by delaying codegen.
The function is not lost. It is in the not-yet-lowered part of the rlib because the compiler has deduced that the function should be made eligible for cross-crate inlining, and rustc implements cross-crate-inlining by delaying codegen.
Hmm... ok, that certainly explains what I'm seeing, but surely that's a bug, no? In the sense, foo1 should end up in the dylib, regardless of whether it is a candidate for cross-crate inlining.
In the sense, foo1 should end up in the dylib, regardless of whether it is a candidate for cross-crate inlining.
It only needs to end up in the dylib if there is a possibility that a crate will depend on it without locally codegening it. All candidates for cross-crate inlining are codegened in the crate that calls them even if LLVM decides not to inline them.
In the sense, foo1 should end up in the dylib, regardless of whether it is a candidate for cross-crate inlining.
It only needs to end up in the dylib if there is a possibility that a crate will depend on it without locally codegening it. All candidates for cross-crate inlining are codegened in the crate that calls them even if LLVM decides not to inline them.
I understand that all items need #[no_mangle] if one wants to use them externally.
What I'm having trouble understanding is, if all you have is a dylib (e.g. the above liba.so that lacks foo1), how are you going to "codegen in the crate that calls them"? Where does the source (or MIR) come from?
Also it seems the behaviour is not really consistent when comparing different crate types.
Suppose we have this:
Then it seems the inline hint is ignored in case of staticlib:
For staticlib and cdylib any function not callable by C will be omitted as they are meant for exporting an api to C code, unlike the dylib crate type which is mostly meant for use by rust code. Only functions with #[no_mangle] can be called by C.
Then it seems the inline hint is ignored in case of staticlib:
For staticlib and cdylib any function not callable by C will be omitted as they are meant for exporting an api to C code, unlike the dylib crate type which is mostly meant for use by rust code. Only functions with #[no_mangle] can be called by C.
Sounds reasonable. Thanks for clarifying!
Am going to close this as things seem to be working as intended.
Activity
saethlin commentedon Oct 24, 2023
The symbol is not missing. Only symbols with
#[no_mangle]are guaranteed to be in the generated code for a library.istankovic commentedon Oct 24, 2023
Well, without
#[no_mangle]I was not able to find it in the generated library.Do you see
foo1in the generated library without using#[no_mangle]?But without using
#[no_mangle], I can getfoo2, but notfoo1. It looks like it is not the lack of#[no_mangle]onfoo1that is causing it to be ignored when building the library, but rather the fact that it usesis_some(). Somehow usingis_some()causesfoo1to be lost somewhere in the MIR -> LLVM IR process.saethlin commentedon Oct 24, 2023
I wrote the PR that caused this change. The function is not lost. It is in the not-yet-lowered part of the rlib because the compiler has deduced that the function should be made eligible for cross-crate inlining, and rustc implements cross-crate-inlining by delaying codegen.
istankovic commentedon Oct 25, 2023
Do you maybe have a link to the PR? I'm curious.
Hmm... ok, that certainly explains what I'm seeing, but surely that's a bug, no? In the sense,
foo1should end up in the dylib, regardless of whether it is a candidate for cross-crate inlining.bjorn3 commentedon Oct 25, 2023
#116505
It only needs to end up in the dylib if there is a possibility that a crate will depend on it without locally codegening it. All candidates for cross-crate inlining are codegened in the crate that calls them even if LLVM decides not to inline them.
istankovic commentedon Oct 25, 2023
Thanks!
I understand that all items need
#[no_mangle]if one wants to use them externally.What I'm having trouble understanding is, if all you have is a dylib (e.g. the above
liba.sothat lacksfoo1), how are you going to "codegen in the crate that calls them"? Where does the source (or MIR) come from?Also it seems the behaviour is not really consistent when comparing different crate types.
Suppose we have this:
Then it seems the inline hint is ignored in case of staticlib:
bjorn3 commentedon Oct 25, 2023
The crate metadata stored in the dylib.
For staticlib and cdylib any function not callable by C will be omitted as they are meant for exporting an api to C code, unlike the dylib crate type which is mostly meant for use by rust code. Only functions with
#[no_mangle]can be called by C.istankovic commentedon Oct 26, 2023
Ah... 👍
Sounds reasonable. Thanks for clarifying!
Am going to close this as things seem to be working as intended.