{"id":"7109f84ddec95c5c","repo":"rust-lang/cargo","slug":"artifact-dep","errorCode":null,"errorMessage":"artifact dep","messagePattern":"artifact dep","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/compiler/unit_dependencies.rs","lineNumber":552,"sourceCode":"    // This is essentially the same as `calc_artifact_deps`, but there are some\n    // subtle differences that require this to be implemented differently.\n    //\n    // Produce units that build all required artifact kinds (like binaries,\n    // static libraries, etc) with the correct compile target.\n    //\n    // Computing the compile target for artifact units is more involved as it has to handle\n    // various target configurations specific to artifacts, like `target = \"target\"` and\n    // `target = \"<triple>\"`, which makes knowing the root units compile target\n    // `root_unit_compile_target` necessary.\n    let root_unit_compile_target = unit_for.root_compile_kind();\n    let unit_for = UnitFor::new_host(/*host_features*/ true, root_unit_compile_target);\n    for (dep_pkg_id, deps) in state.deps(unit, script_unit_for) {\n        for dep in deps {\n            if dep.kind() != DepKind::Build || dep.artifact().is_none() {\n                continue;\n            }\n            let artifact_pkg = state.get(dep_pkg_id);\n            let artifact = dep.artifact().expect(\"artifact dep\");\n            let resolved_artifact_compile_kind = artifact\n                .target()\n                .map(|target| target.to_resolved_compile_kind(root_unit_compile_target));\n\n            result.extend(artifact_targets_to_unit_deps(\n                unit,\n                unit_for.with_artifact_features_from_resolved_compile_kind(\n                    resolved_artifact_compile_kind,\n                ),\n                state,\n                resolved_artifact_compile_kind.unwrap_or(CompileKind::Host),\n                artifact_pkg,\n                dep,\n            )?);\n        }\n    }\n\n    Ok(result)","sourceCodeStart":534,"sourceCodeEnd":570,"githubUrl":"https://github.com/rust-lang/cargo/blob/0e07a155371a6ce88ae53a2c00df940280c09a67/src/compiler/unit_dependencies.rs#L534-L570","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Update cargo to a version that stabilizes or fixes artifact-dependency handling.","Remove the artifact dependency temporarily and verify the build succeeds without it, confirming it is the trigger.","Regenerate Cargo.lock (rm Cargo.lock && cargo generate-lockfile) to ensure consistent dependency metadata.","File a cargo bug with the minimal Cargo.toml reproducer using the artifact dep syntax."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before relying on artifact deps, verify each dep's artifact field\nfor (dep_pkg_id, deps) in state.deps(unit, unit_for) {\n    for dep in deps {\n        if dep.kind() == DepKind::Build && dep.artifact().is_some() {\n            // safe to call dep.artifact().unwrap()\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep artifact dependency declarations simple and well-formed in Cargo.toml.","Regenerate Cargo.lock after changing artifact deps to ensure consistent metadata.","Test artifact deps on the latest nightly/stable cargo before relying on them in CI."],"tags":["rust","cargo","panic","invariant","artifact-deps","unstable"],"analyzedSha":"0e07a155371a6ce88ae53a2c00df940280c09a67","analyzedAt":"2026-08-06T01:46:58.334Z","schemaVersion":2}