-
-
Notifications
You must be signed in to change notification settings - Fork 14.5k
Description
Problem: #[no_link] does not prevent an extern crate from being linked.
Steps to reproduce:
macro_crate/Cargo.toml:
[package]
name = "macro_crate"
version = "0.1.0"
edition = "2021"macro_crate/src/lib.rs:
#[macro_export]
macro_rules! square {
($x:expr) => {
$x * $x
};
}
pub fn add(x: i32, y: i32) -> i32 {
x + y
}Cargo.toml:
[package]
name = "no_link_bug"
version = "0.1.0"
edition = "2024"
[dependencies]
macro_crate = { path = "../macro_crate" }src/main.rs:
#[no_link]
extern crate macro_crate;
fn main() {
let num = 4;
let squared = macro_crate::square!(num);
println!("{} squared is {}", num, squared);
let sum = macro_crate::add(1, 2);
println!("1 + 2 = {}", sum);
}Expected behavior:
The build should fail with a linker error, for example:
rust-lld: error: undefined symbol: macro_crate::add::hd706c5be871dff6f
Actual behavior:
The build succeeds and produces a binary.
Meta:
rustc 1.95.0-nightly (c04308580 2026-02-18)
binary: rustc
commit-hash: c043085801b7a884054add21a94882216df5971c
commit-date: 2026-02-18
host: x86_64-unknown-linux-gnu
release: 1.95.0-nightly
LLVM version: 22.1.0
cargo 1.95.0-nightly (ce69df6f7 2026-02-12)
Linux x86_64
Verbose build output:
Verbose output
RUST_BACKTRACE=1 cargo build -vv
Compiling macro_crate v0.1.0 (/home/mmoro/Projects/no_link_bug/macro_crate)
Running `CARGO=/home/mmoro/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/cargo CARGO_CRATE_NAME=macro_crate CARGO_MANIFEST_DIR=/home/mmoro/Projects/no_link_bug/macro_crate CARGO_MANIFEST_PATH=/home/mmoro/Projects/no_link_bug/macro_crate/Cargo.toml CARGO_PKG_AUTHORS='' CARGO_PKG_DESCRIPTION='' CARGO_PKG_HOMEPAGE='' CARGO_PKG_LICENSE='' CARGO_PKG_LICENSE_FILE='' CARGO_PKG_NAME=macro_crate CARGO_PKG_README='' CARGO_PKG_REPOSITORY='' CARGO_PKG_RUST_VERSION='' CARGO_PKG_VERSION=0.1.0 CARGO_PKG_VERSION_MAJOR=0 CARGO_PKG_VERSION_MINOR=1 CARGO_PKG_VERSION_PATCH=0 CARGO_PKG_VERSION_PRE='' LD_LIBRARY_PATH='/home/mmoro/Projects/no_link_bug/target/debug/deps:/home/mmoro/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib' /home/mmoro/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/rustc --crate-name macro_crate --edition=2021 macro_crate/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=192 --crate-type rlib --emit=dep-info,metadata,link -C embed-bitcode=no -C debuginfo=2 --check-cfg 'cfg(docsrs,test)' --check-cfg 'cfg(feature, values())' -C metadata=1ffd961baa1102b0 -C extra-filename=-c0993a15f8871f25 --out-dir /home/mmoro/Projects/no_link_bug/target/debug/deps -C incremental=/home/mmoro/Projects/no_link_bug/target/debug/incremental -L dependency=/home/mmoro/Projects/no_link_bug/target/debug/deps`
Compiling no_link_bug v0.1.0 (/home/mmoro/Projects/no_link_bug)
Running `CARGO=/home/mmoro/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/cargo CARGO_BIN_NAME=no_link_bug CARGO_CRATE_NAME=no_link_bug CARGO_MANIFEST_DIR=/home/mmoro/Projects/no_link_bug CARGO_MANIFEST_PATH=/home/mmoro/Projects/no_link_bug/Cargo.toml CARGO_PKG_AUTHORS='' CARGO_PKG_DESCRIPTION='' CARGO_PKG_HOMEPAGE='' CARGO_PKG_LICENSE='' CARGO_PKG_LICENSE_FILE='' CARGO_PKG_NAME=no_link_bug CARGO_PKG_README='' CARGO_PKG_REPOSITORY='' CARGO_PKG_RUST_VERSION='' CARGO_PKG_VERSION=0.1.0 CARGO_PKG_VERSION_MAJOR=0 CARGO_PKG_VERSION_MINOR=1 CARGO_PKG_VERSION_PATCH=0 CARGO_PKG_VERSION_PRE='' CARGO_PRIMARY_PACKAGE=1 LD_LIBRARY_PATH='/home/mmoro/Projects/no_link_bug/target/debug/deps:/home/mmoro/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib' /home/mmoro/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/rustc --crate-name no_link_bug --edition=2024 src/main.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=192 --crate-type bin --emit=dep-info,link -C embed-bitcode=no -C debuginfo=2 --check-cfg 'cfg(docsrs,test)' --check-cfg 'cfg(feature, values())' -C metadata=6bf287f543d40f7f -C extra-filename=-838203c1bd20a69b --out-dir /home/mmoro/Projects/no_link_bug/target/debug/deps -C incremental=/home/mmoro/Projects/no_link_bug/target/debug/incremental -L dependency=/home/mmoro/Projects/no_link_bug/target/debug/deps --extern macro_crate=/home/mmoro/Projects/no_link_bug/target/debug/deps/libmacro_crate-c0993a15f8871f25.rlib`
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.25s
My thoughts:
When rustc is invoked with --extern macro_crate=…/*.rlib, the crate is initially loaded as Unconditional. Later, when the compiler sees #[no_link] extern crate macro_crate, it attempts to downgrade it to MacrosOnly. However, maybe_resolve_crate uses cmp::max when updating the crate’s dep_kind, so the Unconditional status is retained. As a result, the crate is still linked, and functions like macro_crate::add are available, causing the build to succeed rather than produce a linker error.