rust-lang / rust-lang/rust

-Ctarget-feature=+crt-static always wins over -crt-static regardless of order (should be last-wins)

Open Beginner friendly
#154,388 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

C-bug needs-triage
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

When running:

rustc --target x86_64-unknown-linux-musl -Ctarget-feature=+crt-static -Ctarget-feature=-crt-static --print cfg | grep crt

I expected to see this happen: No output, because -crt-static appears last and should override +crt-static, consistent with how other -C flags work (last wins). For example, -Cforce-unwind-tables=no -Cforce-unwind-tables=yes correctly produces yes.

Instead, this happened: target_feature="crt-static" is still present — +crt-static always wins regardless of order.


The root cause is in session.rs:374-377:

let found_negative = requested_features.clone().any(|r| r == "-crt-static");
let found_positive = requested_features.clone().any(|r| r == "+crt-static");

if found_positive || found_negative {
    found_positive
}

This uses any() which is order-independent. This means if +crt-static appears anywhere in the features, found_positive is true and the function returns true. Compare with other -C flags like force-unwind-tables which use parse_opt_bool with *slot = Some(value), where each occurrence overwrites the previous (last wins).

This makes it impossible to override +crt-static from .cargo/config.toml via Cargo's --config mechanism, which appends flags rather than replacing them. This is a blocker for use cases like AddressSanitizer where ASAN requires -crt-static but the project's base config sets +crt-static for all musl builds.

Suggested fix: Replace the any() logic with iteration that tracks the last occurrence:

let mut crt_static = None;
for feature in requested_features {
    match feature {
        "+crt-static" => crt_static = Some(true),
        "-crt-static" => crt_static = Some(false),
        _ => {}
    }
}

if let Some(val) = crt_static {
    val
} else if /* proc-macro check */ {
    false
} else {
    self.target.crt_static_default
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in compiler/rustc_session/src/session.rs around lines 374-377 and reproduce the provided rustc command for the musl target. Verify that repeated crt-static flags follow last-wins behavior, with -crt-static removing target_feature="crt-static" when it appears last.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.