From f34b989b58a028f1c5323941bd68516f639c1ecb Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 22 May 2018 08:24:46 -0700 Subject: [PATCH] Fix panic in `cargo metadata` with dep on bin This fixes an accidental `unwrap` on a package which doesn't actually have a lib target in `cargo metadata`. It also refactors along the way to return a `Result` to propagate the error from `packages.get` Closes #5548 --- src/cargo/ops/cargo_output_metadata.rs | 63 ++++++++++++-------------- tests/testsuite/metadata.rs | 32 +++++++++++++ 2 files changed, 62 insertions(+), 33 deletions(-) diff --git a/src/cargo/ops/cargo_output_metadata.rs b/src/cargo/ops/cargo_output_metadata.rs index c7d3c3ce851..c423a8f174d 100644 --- a/src/cargo/ops/cargo_output_metadata.rs +++ b/src/cargo/ops/cargo_output_metadata.rs @@ -59,7 +59,7 @@ fn metadata_full(ws: &Workspace, opt: &OutputMetadataOptions) -> CargoResult, - ) -> MetadataResolve { - let nodes = resolve - .iter() - .map(|pkg| { - Node { - id: pkg.clone(), - dependencies: resolve.deps(pkg).map(|(dep, _)| dep.clone()).collect(), - deps: resolve - .deps(pkg) - .flat_map(|(id, deps)| { - let dep_name = packages.get(id).unwrap() - .lib_target().unwrap() - .crate_name(); - deps.iter().map(|dep| { - Dependency { - id: id.clone(), - name: dep.rename().unwrap_or(&dep_name) - .to_owned(), - kind: dep.kind(), - } - }).collect::>().into_iter() - }) - .collect(), - features: resolve - .features_sorted(pkg) - .into_iter() - .map(|s| s.to_string()) - .collect(), - } - }) - .collect(); - MetadataResolve { nodes, root } + ) -> CargoResult { + let mut nodes = Vec::new(); + for pkg in resolve.iter() { + let mut deps = Vec::new(); + for (id, resolve_deps) in resolve.deps(pkg) { + let dep_name = match packages.get(id)?.lib_target() { + Some(t) => t.crate_name(), + None => continue, + }; + deps.extend(resolve_deps.iter().map(move |dep| { + Dependency { + id: id.clone(), + name: dep.rename().unwrap_or(&dep_name).to_owned(), + kind: dep.kind(), + } + })); + } + nodes.push(Node { + id: pkg.clone(), + dependencies: resolve.deps(pkg).map(|(dep, _)| dep.clone()).collect(), + deps, + features: resolve + .features_sorted(pkg) + .into_iter() + .map(|s| s.to_string()) + .collect(), + }); + } + Ok(MetadataResolve { nodes, root }) } } diff --git a/tests/testsuite/metadata.rs b/tests/testsuite/metadata.rs index de0c0afb41d..9f191cfd711 100644 --- a/tests/testsuite/metadata.rs +++ b/tests/testsuite/metadata.rs @@ -1248,3 +1248,35 @@ fn package_metadata() { ), ); } + +#[test] +fn bin_lib() { + let p = project("foo") + .file( + "foo/Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + "#, + ) + .file("foo/src/main.rs", "") + .file( + "bar/Cargo.toml", + r#" + [package] + name = "bar" + version = "0.1.0" + + [dependencies] + foo = { path = "../foo" } + "#, + ) + .file("bar/src/lib.rs", "") + .build(); + + assert_that( + p.cargo("metadata").cwd(p.root().join("bar")), + execs().with_status(0), + ); +}