rust-lang/cargo · error

artifact dep

Error message

artifact dep

What it means

This panic is in calc_script_deps_for_artifact_deps(), which builds compile units for artifact dependencies (deps declared with artifact = "bin" / "staticlib" / etc. in Cargo.toml). The loop on line 548 skips any dep where dep.artifact() is None, so by line 552 dep.artifact() is guaranteed Some. The .expect() asserts this invariant — if it fires, the control-flow guard above was bypassed.

Source

Thrown at src/compiler/unit_dependencies.rs:552

    // This is essentially the same as `calc_artifact_deps`, but there are some
    // subtle differences that require this to be implemented differently.
    //
    // Produce units that build all required artifact kinds (like binaries,
    // static libraries, etc) with the correct compile target.
    //
    // Computing the compile target for artifact units is more involved as it has to handle
    // various target configurations specific to artifacts, like `target = "target"` and
    // `target = "<triple>"`, which makes knowing the root units compile target
    // `root_unit_compile_target` necessary.
    let root_unit_compile_target = unit_for.root_compile_kind();
    let unit_for = UnitFor::new_host(/*host_features*/ true, root_unit_compile_target);
    for (dep_pkg_id, deps) in state.deps(unit, script_unit_for) {
        for dep in deps {
            if dep.kind() != DepKind::Build || dep.artifact().is_none() {
                continue;
            }
            let artifact_pkg = state.get(dep_pkg_id);
            let artifact = dep.artifact().expect("artifact dep");
            let resolved_artifact_compile_kind = artifact
                .target()
                .map(|target| target.to_resolved_compile_kind(root_unit_compile_target));

            result.extend(artifact_targets_to_unit_deps(
                unit,
                unit_for.with_artifact_features_from_resolved_compile_kind(
                    resolved_artifact_compile_kind,
                ),
                state,
                resolved_artifact_compile_kind.unwrap_or(CompileKind::Host),
                artifact_pkg,
                dep,
            )?);
        }
    }

    Ok(result)

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Update cargo to a version that stabilizes or fixes artifact-dependency handling.
  2. Remove the artifact dependency temporarily and verify the build succeeds without it, confirming it is the trigger.
  3. Regenerate Cargo.lock (rm Cargo.lock && cargo generate-lockfile) to ensure consistent dependency metadata.
  4. File a cargo bug with the minimal Cargo.toml reproducer using the artifact dep syntax.
Defensive patterns

Strategy: validation

Validate before calling

// Before relying on artifact deps, verify each dep's artifact field
for (dep_pkg_id, deps) in state.deps(unit, unit_for) {
    for dep in deps {
        if dep.kind() == DepKind::Build && dep.artifact().is_some() {
            // safe to call dep.artifact().unwrap()
        }
    }
}

Prevention

When it happens

Trigger: Having an artifact dependency (e.g., [dependencies] foo = { version = "1", artifact = "bin" }) where the dependency's artifact field was cleared or mutated between the is_none() check on line 548 and the expect on line 552 — which would require a data race or interior mutation bug in cargo's dependency model.

Common situations: Using artifact dependencies (a -Z unstable feature) with a cargo version that has a known bug in its dependency-resolution pipeline; concurrent or re-entrant calls into the unit-dependency graph builder; corrupted Cargo.lock or manifest causing inconsistent dep metadata.

Related errors


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