Skip to content

Commit f34b989

Browse files
committed
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
1 parent 64f8f1b commit f34b989

File tree

2 files changed

+62
-33
lines changed

2 files changed

+62
-33
lines changed

src/cargo/ops/cargo_output_metadata.rs

Lines changed: 30 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ fn metadata_full(ws: &Workspace, opt: &OutputMetadataOptions) -> CargoResult<Exp
5959
&packages,
6060
&resolve,
6161
ws.current_opt().map(|pkg| pkg.package_id().clone()),
62-
);
62+
)?;
6363
let packages = packages
6464
.package_ids()
6565
.map(|i| packages.get(i).map(|p| p.clone()))
@@ -130,37 +130,34 @@ impl MetadataResolve {
130130
packages: &PackageSet,
131131
resolve: &Resolve,
132132
root: Option<PackageId>,
133-
) -> MetadataResolve {
134-
let nodes = resolve
135-
.iter()
136-
.map(|pkg| {
137-
Node {
138-
id: pkg.clone(),
139-
dependencies: resolve.deps(pkg).map(|(dep, _)| dep.clone()).collect(),
140-
deps: resolve
141-
.deps(pkg)
142-
.flat_map(|(id, deps)| {
143-
let dep_name = packages.get(id).unwrap()
144-
.lib_target().unwrap()
145-
.crate_name();
146-
deps.iter().map(|dep| {
147-
Dependency {
148-
id: id.clone(),
149-
name: dep.rename().unwrap_or(&dep_name)
150-
.to_owned(),
151-
kind: dep.kind(),
152-
}
153-
}).collect::<Vec<_>>().into_iter()
154-
})
155-
.collect(),
156-
features: resolve
157-
.features_sorted(pkg)
158-
.into_iter()
159-
.map(|s| s.to_string())
160-
.collect(),
161-
}
162-
})
163-
.collect();
164-
MetadataResolve { nodes, root }
133+
) -> CargoResult<MetadataResolve> {
134+
let mut nodes = Vec::new();
135+
for pkg in resolve.iter() {
136+
let mut deps = Vec::new();
137+
for (id, resolve_deps) in resolve.deps(pkg) {
138+
let dep_name = match packages.get(id)?.lib_target() {
139+
Some(t) => t.crate_name(),
140+
None => continue,
141+
};
142+
deps.extend(resolve_deps.iter().map(move |dep| {
143+
Dependency {
144+
id: id.clone(),
145+
name: dep.rename().unwrap_or(&dep_name).to_owned(),
146+
kind: dep.kind(),
147+
}
148+
}));
149+
}
150+
nodes.push(Node {
151+
id: pkg.clone(),
152+
dependencies: resolve.deps(pkg).map(|(dep, _)| dep.clone()).collect(),
153+
deps,
154+
features: resolve
155+
.features_sorted(pkg)
156+
.into_iter()
157+
.map(|s| s.to_string())
158+
.collect(),
159+
});
160+
}
161+
Ok(MetadataResolve { nodes, root })
165162
}
166163
}

tests/testsuite/metadata.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,3 +1248,35 @@ fn package_metadata() {
12481248
),
12491249
);
12501250
}
1251+
1252+
#[test]
1253+
fn bin_lib() {
1254+
let p = project("foo")
1255+
.file(
1256+
"foo/Cargo.toml",
1257+
r#"
1258+
[package]
1259+
name = "foo"
1260+
version = "0.1.0"
1261+
"#,
1262+
)
1263+
.file("foo/src/main.rs", "")
1264+
.file(
1265+
"bar/Cargo.toml",
1266+
r#"
1267+
[package]
1268+
name = "bar"
1269+
version = "0.1.0"
1270+
1271+
[dependencies]
1272+
foo = { path = "../foo" }
1273+
"#,
1274+
)
1275+
.file("bar/src/lib.rs", "")
1276+
.build();
1277+
1278+
assert_that(
1279+
p.cargo("metadata").cwd(p.root().join("bar")),
1280+
execs().with_status(0),
1281+
);
1282+
}

0 commit comments

Comments
 (0)