Skip to content

Incremental compilation fails when a generic function uses a private symbol #53929

Open
@mjbshaw

Description

@mjbshaw

The way that incremental compilation works breaks code that uses private symbols. For example, the following code will fail to compile when using incremental compilation (e.g. the default cargo build), but will build successfully when incremental compilation is disabled (e.g. the default cargo build --release):

// I have reproduced this issue for the following targets:
// mips-unknown-linux-gnu
// x86_64-unknown-linux-gnu
// x86_64-apple-darwin
// aarch64-apple-ios
fn foo<T>() {
    // See m:<mangling> at https://llvm.org/docs/LangRef.html#data-layout
    // This is only reproducible when using ELF, Mips, or Mach-O mangling.
    #[cfg_attr(all(target_os = "linux", not(target_arch = "mips")),
               export_name = "\x01.L_this_is_a_private_symbol")]
    #[cfg_attr(any(target_os = "macos", target_os = "ios"),
               export_name = "\x01L_this_is_a_private_symbol")]
    #[cfg_attr(target_arch = "mips", export_name = "\x01$_this_is_a_private_symbol")]
    static X: usize = 0;

    // Use the static symbol in a way that prevents the optimizer from
    // optimizing it away.
    unsafe { std::ptr::read_volatile(&X as *const _); }
}

fn main() {
    foo::<usize>();
}

Output (for both cargo build and cargo build --release):

$ cargo build
   Compiling zzz v0.1.0 (file:///private/tmp/zzz)
LLVM ERROR: unsupported relocation of undefined symbol 'L_this_is_a_private_symbol'
error: Could not compile `zzz`.

To learn more, run the command again with --verbose.
$ cargo build --release
   Compiling zzz v0.1.0 (file:///private/tmp/zzz)
    Finished release [optimized] target(s) in 0.26s

I have reproduced this issue for the following targets:

  • mips-unknown-linux-gnu
  • x86_64-unknown-linux-gnu
  • x86_64-apple-darwin
  • aarch64-apple-ios

I'm interested in fixing this issue, and have been trying to better understand librustc_mir/monomorphize/partitioning.rs (which I assume is where the problem is). I'll update this issue if I've made any progress, but I would appreciate any guidance anyone might be able to offer.

These private symbols are useful for low-level FFI work (e.g. the linker on macOS/iOS will deduplicate selector names only if they have a private symbol name).

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-linkageArea: linking into static, shared libraries and binariesC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions