rust-lang/cargo · error

std has a lib

Error message

std has a lib

What it means

While generating std root units, `generate_std_roots` finds each package's library target via `.find(|t| t.is_lib()).expect("std has a lib")`. Every std-workspace crate that Cargo asks to build is expected to expose a `lib` target. The panic means a requested std crate has no library target — it was asked for by name but contributes only a bin/example/etc.

Source

Thrown at src/compiler/standard_lib.rs:182

    std_features: &ResolvedFeatures,
    kinds: &[&CompileKind],
    package_set: &PackageSet<'_>,
    interner: &UnitInterner,
    profiles: &Profiles,
    target_data: &RustcTargetData<'_>,
) -> CargoResult<()> {
    let std_ids = std_crates(crates, default, units)
        .iter()
        .map(|crate_name| std_resolve.query(crate_name))
        .collect::<CargoResult<Vec<PackageId>>>()?;
    let std_pkgs = package_set.get_many(std_ids)?;

    for pkg in std_pkgs {
        let lib = pkg
            .targets()
            .iter()
            .find(|t| t.is_lib())
            .expect("std has a lib");
        // I don't think we need to bother with Check here, the difference
        // in time is minimal, and the difference in caching is
        // significant.
        let mode = CompileMode::Build;
        let features = std_features.activated_features(pkg.package_id(), FeaturesFor::NormalOrDev);
        for kind in kinds {
            let kind = **kind;
            let list = ret.entry(kind).or_insert_with(Vec::new);
            let unit_for = UnitFor::new_normal(kind);
            let profile = profiles.get_profile(
                pkg.package_id(),
                /*is_member*/ false,
                /*is_local*/ false,
                unit_for,
                kind,
            );
            list.push(interner.intern(
                pkg,

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Restrict `-Zbuild-std` to library crates of the std workspace (typically `std`, `core`, `alloc`, `proc_macro`, `panic_abort`, `panic_unwind`, `compiler_builtins`).
  2. `rustup component add rust-src` and use the matching nightly Cargo.
  3. If you maintain a patched rust-src, ensure each requested crate has a `[lib]` target.

Example fix

// before
let lib = pkg
    .targets()
    .iter()
    .find(|t| t.is_lib())
    .expect("std has a lib");
// after
let lib = pkg
    .targets()
    .iter()
    .find(|t| t.is_lib())
    .ok_or_else(|| anyhow::anyhow!("std crate `{}` has no lib target", pkg.package_id()))?;
Defensive patterns

Strategy: validation

Validate before calling

// Confirm each requested -Zbuild-std crate has a lib target in the std source tree
fn crate_has_lib(std_src: &std::path::Path, name: &str) -> bool {
    std::fs::read_to_string(std_src.join(name).join("Cargo.toml"))
        .map(|t| t.contains("[lib]") || !t.contains("[[bin]]"))
        .unwrap_or(false)
}

Prevention

When it happens

Trigger: Passing `-Zbuild-std=<name>` where `<name>` is a std-workspace crate without a lib target (e.g. a tools/binary crate), or a rust-src layout where the `Cargo.toml` lacks a `[lib]`/auto-detected lib; a Cargo/std-source version mismatch where a crate's target set changed.

Common situations: Hand-tuning `-Zbuild-std` to include non-library crates; pointing `__CARGO_TESTS_ONLY_SRC_ROOT` at a modified std source tree; mismatched rust-src and Cargo expectations on nightly.

Related errors


AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06). Data as JSON: /data/errors/85f48d03586947e9.json. Report an issue: GitHub.