Repository: cross-rs/cross
Pull request #915 (2022-07-06 12:41:02)

more clippy

Alexhuszagh: Fix the `to_string` warnings on Windows and then lgtm.

Patch:
diff --git a/clippy.toml b/clippy.toml
index e6edaa1..2b7937a 100644
--- a/clippy.toml
+++ b/clippy.toml
@@ -1,3 +1,5 @@
 disallowed-methods = [
     { path = "std::path::Path::display", reason = "incorrect handling of non-Unicode paths, use path.to_utf8() or debug (`{path:?}`) instead" },
 ]
+# needs clippy 1.61
+# allow-unwrap-in-tests = true
diff --git a/src/cargo.rs b/src/cargo.rs
index 90662cf..f80d29f 100644
--- a/src/cargo.rs
+++ b/src/cargo.rs
@@ -24,6 +24,7 @@ pub enum Subcommand {
 }
 
 impl Subcommand {
+    #[must_use]
     pub fn needs_docker(self, is_remote: bool) -> bool {
         match self {
             Subcommand::Other | Subcommand::List => false,
@@ -32,14 +33,17 @@ impl Subcommand {
         }
     }
 
+    #[must_use]
     pub fn needs_host(self, is_remote: bool) -> bool {
         self == Subcommand::Clean && is_remote
     }
 
+    #[must_use]
     pub fn needs_interpreter(self) -> bool {
         matches!(self, Subcommand::Run | Subcommand::Test | Subcommand::Bench)
     }
 
+    #[must_use]
     pub fn needs_target_in_command(self) -> bool {
         !matches!(self, Subcommand::Metadata)
     }
@@ -85,6 +89,7 @@ impl CargoMetadata {
     }
 
     #[cfg(feature = "dev")]
+    #[must_use]
     pub fn get_package(&self, package: &str) -> Option<&Package> {
         self.packages.iter().find(|p| p.name == package)
     }
@@ -112,6 +117,7 @@ impl Package {
     }
 }
 
+#[must_use]
 pub fn cargo_command() -> Command {
     Command::new("cargo")
 }
diff --git a/src/cli.rs b/src/cli.rs
index c0f9120..5d618a5 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -55,13 +55,13 @@ pub fn fmt_subcommands(stdout: &str, msg_info: &mut MessageInfo) -> Result<()> {
     let (cross, host) = group_subcommands(stdout);
     if !cross.is_empty() {
         msg_info.print("Cross Commands:")?;
-        for line in cross.iter() {
+        for line in &cross {
             msg_info.print(line)?;
         }
     }
     if !host.is_empty() {
         msg_info.print("Host Commands:")?;
-        for line in cross.iter() {
+        for line in &cross {
             msg_info.print(line)?;
         }
     }
@@ -116,7 +116,7 @@ fn parse_next_arg<T>(
 }
 
 fn parse_equal_arg<T>(arg: String, out: &mut Vec<String>, parse: impl Fn(&str) -> T) -> T {
-    let result = parse(arg.split_once('=').unwrap().1);
+    let result = parse(arg.split_once('=').expect("argument should contain `=`").1);
     out.push(arg);
 
     result
@@ -177,7 +177,7 @@ pub fn parse(target_list: &TargetList) -> Result<Args> {
                     ArgKind::Equal => parse_equal_arg(arg, &mut all, parse_manifest_path),
                 };
             } else if let ("+", ch) = arg.split_at(1) {
-                channel = Some(ch.to_string());
+                channel = Some(ch.to_owned());
             } else if let Some(kind) = is_value_arg(&arg, "--target") {
                 target = match kind {
                     ArgKind::Next => {
@@ -196,7 +196,7 @@ pub fn parse(target_list: &TargetList) -> Result<Args> {
                         }
                     }
                     ArgKind::Equal => {
-                        features.push(parse_equal_arg(arg, &mut all, ToOwned::to_owned))
+                        features.push(parse_equal_arg(arg, &mut all, ToOwned::to_owned));
                     }
                 }
             } else if let Some(kind) = is_value_arg(&arg, "--target-dir") {
@@ -205,11 +205,13 @@ pub fn parse(target_list: &TargetList) -> Result<Args> {
                         all.push(arg);
                         if let Some(td) = args.next() {
                             target_dir = Some(parse_target_dir(&td)?);
-                            all.push("/target".to_string());
+                            all.push("/target".to_owned());
                         }
                     }
                     ArgKind::Equal => {
-                        target_dir = Some(parse_target_dir(arg.split_once('=').unwrap().1)?);
+                        target_dir = Some(parse_target_dir(
+                            arg.split_once('=').expect("argument should contain `=`").1,
+                        )?);
                         all.push("--target-dir=/target".into());
                     }
                 }
@@ -218,7 +220,7 @@ pub fn parse(target_list: &TargetList) -> Result<Args> {
                     sc = Some(Subcommand::from(arg.as_ref()));
                 }
 
-                all.push(arg.to_string());
+                all.push(arg.clone());
             }
         }
     }
diff --git a/src/config.rs b/src/config.rs
index 8a9e6c8..4e9fbd2 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -20,7 +20,7 @@ impl Environment {
     fn get_var(&self, name: &str) -> Option<String> {
         self.1
             .as_ref()
-            .and_then(|internal_map| internal_map.get(name).map(|v| v.to_string()))
+            .and_then(|internal_map| internal_map.get(name).map(|v| (*v).to_owned()))
             .or_else(|| env::var(name).ok())
     }
 
@@ -45,7 +45,7 @@ impl Environment {
         if !key.starts_with("BUILD_") {
             format!("BUILD_{key}")
         } else {
-            key.to_string()
+            key.to_owned()
         }
     }
 
@@ -70,11 +70,11 @@ impl Environment {
     }
 
     fn dockerfile(&self, target: &Target) -> (Option<String>, Option<String>) {
-        self.get_values_for("DOCKERFILE", target, |s| s.to_string())
+        self.get_values_for("DOCKERFILE", target, |s| s.to_owned())
     }
 
     fn dockerfile_context(&self, target: &Target) -> (Option<String>, Option<String>) {
-        self.get_values_for("DOCKERFILE_CONTEXT", target, |s| s.to_string())
+        self.get_values_for("DOCKERFILE_CONTEXT", target, |s| s.to_owned())
     }
 
     fn pre_build(&self, target: &Target) -> (Option<Vec<String>>, Option<Vec<String>>) {
@@ -384,8 +384,8 @@ mod tests {
     fn target_list() -> TargetList {
         TargetList {
             triples: vec![
-                "aarch64-unknown-linux-gnu".to_string(),
-                "armv7-unknown-linux-musleabihf".to_string(),
+                "aarch64-unknown-linux-gnu".to_owned(),
+                "armv7-unknown-linux-musleabihf".to_owned(),
             ],
         }
     }
@@ -438,7 +438,7 @@ mod tests {
             assert_eq!(
                 env.build_var_name("target-aarch64-unknown-linux-gnu_image"),
                 "CROSS_TARGET_AARCH64_UNKNOWN_LINUX_GNU_IMAGE"
-            )
+            );
         }
 
         #[test]
@@ -453,10 +453,10 @@ mod tests {
             let env = Environment::new(Some(map));
 
             let (build, target) = env.passthrough(&target());
-            assert!(build.as_ref().unwrap().contains(&"TEST1".to_string()));
-            assert!(build.as_ref().unwrap().contains(&"TEST2".to_string()));
-            assert!(target.as_ref().unwrap().contains(&"PASS1".to_string()));
-            assert!(target.as_ref().unwrap().contains(&"PASS2".to_string()));
+            assert!(build.as_ref().unwrap().contains(&"TEST1".to_owned()));
+            assert!(build.as_ref().unwrap().contains(&"TEST2".to_owned()));
+            assert!(target.as_ref().unwrap().contains(&"PASS1".to_owned()));
+            assert!(target.as_ref().unwrap().contains(&"PASS2".to_owned()));
         }
     }
 
@@ -467,7 +467,7 @@ mod tests {
 
         macro_rules! s {
             ($x:literal) => {
-                $x.to_string()
+                $x.to_owned()
             };
         }
 
@@ -627,7 +627,7 @@ mod tests {
             map.insert("CROSS_BUILD_ENV_VOLUMES", "VOLUME1 VOLUME2");
             let env = Environment::new(Some(map));
             let config = Config::new_with(Some(toml(TOML_BUILD_VOLUMES)?), env);
-            let expected = vec!["VOLUME1".to_string(), "VOLUME2".into()];
+            let expected = vec![s!("VOLUME1"), s!("VOLUME2")];
 
             let result = config.env_volumes(&target()).unwrap().unwrap_or_default();
             dbg!(&result);
@@ -643,7 +643,7 @@ mod tests {
             let map = HashMap::new();
             let env = Environment::new(Some(map));
             let config = Config::new_with(Some(toml(TOML_BUILD_VOLUMES)?), env);
-            let expected = vec!["VOLUME3".to_string(), "VOLUME4".into()];
+            let expected = vec![s!("VOLUME3"), s!("VOLUME4")];
 
             let result = config.env_volumes(&target()).unwrap().unwrap_or_default();
             dbg!(&result);
diff --git a/src/cross_toml.rs b/src/cross_toml.rs
index edb9cb9..2768cf6 100644
--- a/src/cross_toml.rs
+++ b/src/cross_toml.rs
@@ -58,7 +58,7 @@ impl FromStr for CrossTargetDockerfileConfig {
 
     fn from_str(s: &str) -> Result<Self, Self::Err> {
         Ok(CrossTargetDockerfileConfig {
-            file: s.to_string(),
+            file: s.to_owned(),
             context: None,
             build_args: None,
         })
@@ -154,7 +154,7 @@ impl CrossToml {
                 .wrap_err("could not convert CrossToml to serde_json::Value")?
                 .as_object()
             {
-                Ok(obj.to_owned())
+                Ok(obj.clone())
             } else {
                 eyre::bail!("failed to serialize CrossToml as object");
             }
@@ -408,7 +408,7 @@ mod tests {
 
     macro_rules! s {
         ($x:literal) => {
-            $x.to_string()
+            $x.to_owned()
         };
     }
 
@@ -432,13 +432,13 @@ mod tests {
             targets: HashMap::new(),
             build: CrossBuildConfig {
                 env: CrossEnvConfig {
-                    volumes: Some(vec!["VOL1_ARG".to_string(), "VOL2_ARG".to_string()]),
-                    passthrough: Some(vec!["VAR1".to_string(), "VAR2".to_string()]),
+                    volumes: Some(vec![s!("VOL1_ARG"), s!("VOL2_ARG")]),
+                    passthrough: Some(vec![s!("VAR1"), s!("VAR2")]),
                 },
                 xargo: Some(true),
                 build_std: None,
                 default_target: None,
-                pre_build: Some(vec!["echo 'Hello World!'".to_string()]),
+                pre_build: Some(vec![s!("echo 'Hello World!'")]),
                 dockerfile: None,
             },
         };
@@ -465,16 +465,16 @@ mod tests {
         let mut target_map = HashMap::new();
         target_map.insert(
             Target::BuiltIn {
-                triple: "aarch64-unknown-linux-gnu".to_string(),
+                triple: s!("aarch64-unknown-linux-gnu"),
             },
             CrossTargetConfig {
                 env: CrossEnvConfig {
-                    passthrough: Some(vec!["VAR1".to_string(), "VAR2".to_string()]),
-                    volumes: Some(vec!["VOL1_ARG".to_string(), "VOL2_ARG".to_string()]),
+                    passthrough: Some(vec![s!("VAR1"), s!("VAR2")]),
+                    volumes: Some(vec![s!("VOL1_ARG"), s!("VOL2_ARG")]),
                 },
                 xargo: Some(false),
                 build_std: Some(true),
-                image: Some("test-image".to_string()),
+                image: Some(s!("test-image")),
                 runner: None,
                 dockerfile: None,
                 pre_build: Some(vec![]),
@@ -509,22 +509,22 @@ mod tests {
         let mut target_map = HashMap::new();
         target_map.insert(
             Target::BuiltIn {
-                triple: "aarch64-unknown-linux-gnu".to_string(),
+                triple: s!("aarch64-unknown-linux-gnu"),
             },
             CrossTargetConfig {
                 xargo: Some(false),
                 build_std: None,
                 image: None,
                 dockerfile: Some(CrossTargetDockerfileConfig {
-                    file: "Dockerfile.test".to_string(),
+                    file: s!("Dockerfile.test"),
                     context: None,
                     build_args: None,
                 }),
-                pre_build: Some(vec!["echo 'Hello'".to_string()]),
+                pre_build: Some(vec![s!("echo 'Hello'")]),
                 runner: None,
                 env: CrossEnvConfig {
                     passthrough: None,
-                    volumes: Some(vec!["VOL".to_string()]),
+                    volumes: Some(vec![s!("VOL")]),
                 },
             },
         );
diff --git a/src/docker/custom.rs b/src/docker/custom.rs
index 1e6f3cf..0c950ad 100644
--- a/src/docker/custom.rs
+++ b/src/docker/custom.rs
@@ -54,7 +54,7 @@ impl<'a> Dockerfile<'a> {
         let image_name = self.image_name(&options.target, &paths.metadata)?;
         docker_build.args(["--tag", &image_name]);
 
-        for (key, arg) in build_args.into_iter() {
+        for (key, arg) in build_args {
             docker_build.args(["--build-arg", &format!("{}={}", key.as_ref(), arg.as_ref())]);
         }
 
@@ -107,7 +107,7 @@ impl<'a> Dockerfile<'a> {
         match self {
             Dockerfile::File {
                 name: Some(name), ..
-            } => Ok(name.to_string()),
+            } => Ok((*name).to_owned()),
             _ => Ok(format!(
                 "{}{package_name}:{target_triple}-{path_hash}{custom}",
                 CROSS_CUSTOM_DOCKERFILE_IMAGE_PREFIX,
@@ -181,7 +181,7 @@ fn docker_tag_name(file_name: &str) -> String {
 
     // in case all characters were invalid, use a non-empty filename
     if result.is_empty() {
-        result = "empty".to_string();
+        result = "empty".to_owned();
     }
 
     result
@@ -193,7 +193,7 @@ mod tests {
 
     macro_rules! s {
         ($s:literal) => {
-            $s.to_string()
+            $s.to_owned()
         };
     }
 
diff --git a/src/docker/engine.rs b/src/docker/engine.rs
index 1694acf..728f412 100644
--- a/src/docker/engine.rs
+++ b/src/docker/engine.rs
@@ -32,6 +32,7 @@ impl Engine {
         is_remote: Option<bool>,
         msg_info: &mut MessageInfo,
     ) -> Result<Engine> {
+        #[allow(clippy::map_err_ignore)]
         let path = get_container_engine()
             .map_err(|_| eyre::eyre!("no container engine found"))
             .with_suggestion(|| "is docker or podman installed?")?;
@@ -58,6 +59,7 @@ impl Engine {
         })
     }
 
+    #[must_use]
     pub fn needs_remote(&self) -> bool {
         self.is_remote && self.kind == EngineType::Podman
     }
@@ -80,6 +82,7 @@ impl Engine {
         )
     }
 
+    #[must_use]
     pub fn is_remote() -> bool {
         env::var("CROSS_REMOTE")
             .map(|s| bool_from_envvar(&s))
diff --git a/src/docker/local.rs b/src/docker/local.rs
index 1e1b4f8..2d86d3d 100644
--- a/src/docker/local.rs
+++ b/src/docker/local.rs
@@ -75,7 +75,7 @@ pub(crate) fn run(
     if options.needs_custom_image() {
         image = options
             .custom_image_build(&paths, msg_info)
-            .wrap_err("when building custom image")?
+            .wrap_err("when building custom image")?;
     }
 
     docker
diff --git a/src/docker/remote.rs b/src/docker/remote.rs
index 31c487b..100290d 100644
--- a/src/docker/remote.rs
+++ b/src/docker/remote.rs
@@ -71,10 +71,12 @@ impl ContainerState {
         }
     }
 
+    #[must_use]
     pub fn is_stopped(&self) -> bool {
         matches!(self, Self::Exited | Self::DoesNotExist)
     }
 
+    #[must_use]
     pub fn exists(&self) -> bool {
         !matches!(self, Self::DoesNotExist)
     }
@@ -94,9 +96,9 @@ impl VolumeId {
         msg_info: &mut MessageInfo,
     ) -> Result<Self> {
         if volume_exists(engine, toolchain, msg_info)? {
-            Ok(Self::Keep(toolchain.to_string()))
+            Ok(Self::Keep(toolchain.to_owned()))
         } else {
-            Ok(Self::Discard(container.to_string()))
+            Ok(Self::Discard(container.to_owned()))
         }
     }
 }
@@ -203,7 +205,12 @@ pub fn copy_volume_container_xargo(
     let src = xargo_dir.join(&relpath);
     let dst = mount_prefix.join("xargo").join(&relpath);
     if Path::new(&src).exists() {
-        create_volume_dir(engine, container, dst.parent().unwrap(), msg_info)?;
+        create_volume_dir(
+            engine,
+            container,
+            dst.parent().expect("destination should have a parent"),
+            msg_info,
+        )?;
         copy_volume_files(engine, container, &src, &dst, msg_info)?;
     }
 
@@ -236,7 +243,7 @@ pub fn copy_volume_container_cargo(
                 .file_name()
                 .to_utf8()
                 .wrap_err_with(|| format!("when reading file {file:?}"))?
-                .to_string();
+                .to_owned();
             if !basename.starts_with('.') && !matches!(basename.as_ref(), "git" | "registry") {
                 copy_volume_files(engine, container, &file.path(), &dst, msg_info)?;
             }
@@ -475,7 +482,7 @@ fn parse_project_fingerprint(path: &Path) -> Result<FingerprintMap> {
             .split_once('\t')
             .ok_or_else(|| eyre::eyre!("unable to parse fingerprint line '{line}'"))?;
         let modified = epoch + time::Duration::from_millis(timestamp.parse::<u64>()?);
-        result.insert(relpath.to_string(), modified);
+        result.insert(relpath.to_owned(), modified);
     }
 
     Ok(result)
@@ -538,17 +545,12 @@ fn get_fingerprint_difference<'a, 'b>(
     // this can be added or updated
     let changed: Vec<&str> = current
         .iter()
-        .filter(|(ref k, ref v1)| {
-            previous
-                .get(&k.to_string())
-                .map(|ref v2| v1 != v2)
-                .unwrap_or(true)
-        })
+        .filter(|(k, v1)| previous.get(*k).map_or(true, |v2| v1 != &v2))
         .map(|(k, _)| k.as_str())
         .collect();
     let removed: Vec<&str> = previous
         .iter()
-        .filter(|(ref k, _)| !current.contains_key(&k.to_string()))
+        .filter(|(k, _)| !current.contains_key(*k))
         .map(|(k, _)| k.as_str())
         .collect();
     (changed, removed)
@@ -588,7 +590,7 @@ fn remove_volume_file_list(
     const PATH: &str = "/tmp/remove_list";
     let mut script = vec![];
     if msg_info.is_verbose() {
-        script.push("set -x".to_string());
+        script.push("set -x".to_owned());
     }
     script.push(format!(
         "cat \"{PATH}\" | while read line; do
@@ -731,7 +733,10 @@ pub fn unique_toolchain_identifier(sysroot: &Path) -> Result<String> {
         rustc::version_meta()?.commit_hash()
     };
 
-    let toolchain_name = sysroot.file_name().unwrap().to_utf8()?;
+    let toolchain_name = sysroot
+        .file_name()
+        .expect("should be able to get toolchain name")
+        .to_utf8()?;
     let toolchain_hash = path_hash(sysroot)?;
     Ok(format!(
         "cross-{toolchain_name}-{toolchain_hash}-{commit_hash}"
@@ -748,7 +753,12 @@ pub fn unique_container_identifier(
     let package = metadata
         .packages
         .iter()
-        .find(|p| p.manifest_path.parent().unwrap() == workspace_root)
+        .find(|p| {
+            p.manifest_path
+                .parent()
+                .expect("manifest path should have a parent directory")
+                == workspace_root
+        })
         .unwrap_or_else(|| {
             metadata
                 .packages
@@ -852,7 +862,7 @@ pub(crate) fn run(
     // Store to the running container so it can load the needed binaries.
     if let Some(ref nix_store) = dirs.nix_store {
         let nix_string = nix_store.to_utf8()?;
-        volumes.push((nix_string.to_string(), nix_string.to_string()))
+        volumes.push((nix_string.to_owned(), nix_string.to_owned()));
     }
 
     docker.arg("-d");
@@ -928,11 +938,21 @@ pub(crate) fn run(
     }
     let mount_root = if mount_volumes {
         // cannot panic: absolute unix path, must have root
-        let rel_mount_root = dirs.mount_root.strip_prefix('/').unwrap();
+        let rel_mount_root = dirs
+            .mount_root
+            .strip_prefix('/')
+            .expect("mount root should be absolute");
         let mount_root = mount_prefix_path.join(rel_mount_root);
         if !rel_mount_root.is_empty() {
-            create_volume_dir(engine, &container, mount_root.parent().unwrap(), msg_info)
-                .wrap_err("when creating mount root")?;
+            create_volume_dir(
+                engine,
+                &container,
+                mount_root
+                    .parent()
+                    .expect("mount root should have a parent directory"),
+                msg_info,
+            )
+            .wrap_err("when creating mount root")?;
         }
         mount_root
     } else {
@@ -972,17 +992,28 @@ pub(crate) fn run(
         copied.push((&dirs.target, target_dir.clone()));
         target_dir
     };
-    for (src, dst) in volumes.iter() {
+    for (src, dst) in &volumes {
         let src: &Path = src.as_ref();
         if let Some((psrc, pdst)) = copied.iter().find(|(p, _)| src.starts_with(p)) {
             // path has already been copied over
-            let relpath = src.strip_prefix(psrc).unwrap();
+            let relpath = src
+                .strip_prefix(psrc)
+                .expect("source should start with prefix");
             to_symlink.push((pdst.join(relpath), dst));
         } else {
-            let rel_dst = dst.strip_prefix('/').unwrap();
+            let rel_dst = dst
+                .strip_prefix('/')
+                .expect("destination should be absolute");
             let mount_dst = mount_prefix_path.join(rel_dst);
             if !rel_dst.is_empty() {
-                create_volume_dir(engine, &container, mount_dst.parent().unwrap(), msg_info)?;
+                create_volume_dir(
+                    engine,
+                    &container,
+                    mount_dst
+                        .parent()
+                        .expect("destination should have a parent directory"),
+                    msg_info,
+                )?;
             }
             copy(src, &mount_dst, msg_info)?;
         }
@@ -1012,16 +1043,16 @@ pub(crate) fn run(
         }
     }
     if !has_target_dir {
-        final_args.push("--target-dir".to_string());
+        final_args.push("--target-dir".to_owned());
         final_args.push(target_dir_string);
     }
     let mut cmd = cargo_safe_command(options.uses_xargo);
     cmd.args(final_args);
 
     // 5. create symlinks for copied data
-    let mut symlink = vec!["set -e pipefail".to_string()];
+    let mut symlink = vec!["set -e pipefail".to_owned()];
     if msg_info.is_verbose() {
-        symlink.push("set -x".to_string());
+        symlink.push("set -x".to_owned());
     }
     symlink.push(format!(
         "chown -R {uid}:{gid} {mount_prefix}",
@@ -1077,7 +1108,12 @@ symlink_recurse \"${{prefix}}\"
         subcommand(engine, "cp")
             .arg("-a")
             .arg(&format!("{container}:{}", target_dir.as_posix()?))
-            .arg(&dirs.target.parent().unwrap())
+            .arg(
+                &dirs
+                    .target
+                    .parent()
+                    .expect("target directory should have a parent"),
+            )
             .run_and_get_status(msg_info, false)
             .map_err::<eyre::ErrReport, _>(Into::into)?;
     }
diff --git a/src/docker/shared.rs b/src/docker/shared.rs
index d04b1da..696817f 100644
--- a/src/docker/shared.rs
+++ b/src/docker/shared.rs
@@ -46,14 +46,17 @@ impl DockerOptions {
         }
     }
 
+    #[must_use]
     pub fn in_docker(&self) -> bool {
         self.engine.in_docker
     }
 
+    #[must_use]
     pub fn is_remote(&self) -> bool {
         self.engine.is_remote
     }
 
+    #[must_use]
     pub fn needs_custom_image(&self) -> bool {
         self.config
             .dockerfile(&self.target)
@@ -190,6 +193,7 @@ impl DockerPaths {
             .map_err(Into::into)
     }
 
+    #[must_use]
     pub fn in_workspace(&self) -> bool {
         self.workspace_from_cwd().is_ok()
     }
@@ -226,9 +230,8 @@ impl Directories {
         let home_dir =
             home::home_dir().ok_or_else(|| eyre::eyre!("could not find home directory"))?;
         let cargo = home::cargo_home()?;
-        let xargo = env::var_os("XARGO_HOME")
-            .map(PathBuf::from)
-            .unwrap_or_else(|| home_dir.join(".xargo"));
+        let xargo =
+            env::var_os("XARGO_HOME").map_or_else(|| home_dir.join(".xargo"), PathBuf::from);
         let nix_store = env::var_os("NIX_STORE").map(PathBuf::from);
         let target = &metadata.target_directory;
 
@@ -261,7 +264,7 @@ impl Directories {
         #[cfg(not(target_os = "windows"))]
         {
             // NOTE: host root has already found the mount path
-            mount_root = host_root.to_utf8()?.to_string();
+            mount_root = host_root.to_utf8()?.to_owned();
         }
         let mount_cwd = mount_finder.find_path(cwd, false)?;
         let sysroot = mount_finder.find_mount_path(sysroot);
@@ -449,7 +452,7 @@ pub(crate) fn docker_envvars(
         .args(&["-e", &cross_runner]);
     add_cargo_configuration_envvars(docker);
 
-    if let Some(username) = id::username().unwrap() {
+    if let Some(username) = id::username().wrap_err("could not get username")? {
         docker.args(&["-e", &format!("USER={username}")]);
     }
 
@@ -513,7 +516,7 @@ pub(crate) fn docker_mount(
     {
         let (var, value) = validate_env_var(var)?;
         let value = match value {
-            Some(v) => Ok(v.to_string()),
+            Some(v) => Ok(v.to_owned()),
             None => env::var(var),
         };
 
@@ -531,7 +534,7 @@ pub(crate) fn docker_mount(
         let canonical_path = file::canonicalize(path)?;
         let host_path = paths.mount_finder.find_path(&canonical_path, true)?;
         let mount_path = mount_cb(docker, host_path.as_ref())?;
-        store_cb((path.to_utf8()?.to_string(), mount_path));
+        store_cb((path.to_utf8()?.to_owned(), mount_path));
         mount_volumes = true;
     }
 
@@ -546,7 +549,7 @@ pub(crate) fn canonicalize_mount_path(path: &Path) -> Result<String> {
     }
     #[cfg(not(target_os = "windows"))]
     {
-        path.to_utf8().map(|p| p.to_string())
+        path.to_utf8().map(|p| p.to_owned())
     }
 }
 
@@ -577,8 +580,8 @@ pub(crate) fn docker_user_id(docker: &mut Command, engine_type: EngineType) {
 pub(crate) fn docker_userns(docker: &mut Command) {
     let userns = match env::var("CROSS_CONTAINER_USER_NAMESPACE").ok().as_deref() {
         Some("none") => None,
-        None | Some("auto") => Some("host".to_string()),
-        Some(ns) => Some(ns.to_string()),
+        None | Some("auto") => Some("host".to_owned()),
+        Some(ns) => Some(ns.to_owned()),
     };
     if let Some(ns) = userns {
         docker.args(&["--userns", &ns]);
@@ -597,7 +600,7 @@ pub(crate) fn docker_seccomp(
         let seccomp = if engine_type == EngineType::Docker && cfg!(target_os = "windows") {
             // docker on windows fails due to a bug in reading the profile
             // https://github.com/docker/for-win/issues/12760
-            "unconfined".to_string()
+            "unconfined".to_owned()
         } else {
             #[allow(unused_mut)] // target_os = "windows"
             let mut path = metadata
@@ -607,7 +610,7 @@ pub(crate) fn docker_seccomp(
             if !path.exists() {
                 write_file(&path, false)?.write_all(SECCOMP.as_bytes())?;
             }
-            let mut path_string = path.to_utf8()?.to_string();
+            let mut path_string = path.to_utf8()?.to_owned();
             #[cfg(target_os = "windows")]
             if matches!(engine_type, EngineType::Podman | EngineType::PodmanRemote) {
                 // podman weirdly expects a WSL path here, and fails otherwise
@@ -688,8 +691,10 @@ fn dockerinfo_parse_root_mount_path(info: &serde_json::Value) -> Result<MountDet
 fn dockerinfo_parse_user_mounts(info: &serde_json::Value) -> Vec<MountDetail> {
     info.pointer("/0/Mounts")
         .and_then(|v| v.as_array())
-        .map(|v| {
-            let make_path = |v: &serde_json::Value| PathBuf::from(&v.as_str().unwrap());
+        .map_or_else(Vec::new, |v| {
+            let make_path = |v: &serde_json::Value| {
+                PathBuf::from(&v.as_str().expect("docker mount should be defined"))
+            };
             let mut mounts = vec![];
             for details in v {
                 let source = make_path(&details["Source"]);
@@ -701,7 +706,6 @@ fn dockerinfo_parse_user_mounts(info: &serde_json::Value) -> Vec<MountDetail> {
             }
             mounts
         })
-        .unwrap_or_else(Vec::new)
 }
 
 #[derive(Debug, Default)]
@@ -753,14 +757,14 @@ impl MountFinder {
         {
             // On Windows, we can not mount the directory name directly. Instead, we use wslpath to convert the path to a linux compatible path.
             if host {
-                return Ok(path.to_utf8()?.to_string());
+                return Ok(path.to_utf8()?.to_owned());
             } else {
                 return path.as_wslpath();
             }
         }
         #[cfg(not(target_os = "windows"))]
         {
-            return Ok(self.find_mount_path(path).to_utf8()?.to_string());
+            return Ok(self.find_mount_path(path).to_utf8()?.to_owned());
         }
     }
 }
@@ -775,7 +779,7 @@ pub fn path_hash(path: &Path) -> Result<String> {
         .to_string()
         .get(..5)
         .expect("sha1 is expected to be at least 5 characters long")
-        .to_string())
+        .to_owned())
 }
 
 #[cfg(test)]
@@ -790,7 +794,7 @@ mod tests {
         env::remove_var(var);
 
         let rootful = format!("\"engine\" \"--user\" \"{}:{}\"", id::user(), id::group());
-        let rootless = "\"engine\"".to_string();
+        let rootless = "\"engine\"".to_owned();
 
         let test = |engine, expected| {
             let mut cmd = Command::new("engine");
@@ -832,9 +836,9 @@ mod tests {
         let old = env::var(var);
         env::remove_var(var);
 
-        let host = "\"engine\" \"--userns\" \"host\"".to_string();
-        let custom = "\"engine\" \"--userns\" \"custom\"".to_string();
-        let none = "\"engine\"".to_string();
+        let host = "\"engine\" \"--userns\" \"host\"".to_owned();
+        let custom = "\"engine\" \"--userns\" \"custom\"".to_owned();
+        let none = "\"engine\"".to_owned();
 
         let test = |expected| {
             let mut cmd = Command::new("engine");
@@ -899,7 +903,10 @@ mod tests {
 
             let root = match subdir {
                 true => get_cwd()?.join("member"),
-                false => get_cwd()?.parent().unwrap().to_path_buf(),
+                false => get_cwd()?
+                    .parent()
+                    .expect("current directory should have a parent")
+                    .to_path_buf(),
             };
             fs::create_dir_all(&root)?;
             metadata.workspace_root = root;
@@ -1050,7 +1057,7 @@ mod tests {
             assert_eq!(
                 PathBuf::from("/target/path/test"),
                 finder.find_mount_path("/project/target/test")
-            )
+            );
         }
 
         #[test]
diff --git a/src/errors.rs b/src/errors.rs
index 83970e7..7137469 100644
--- a/src/errors.rs
+++ b/src/errors.rs
@@ -58,8 +58,8 @@ impl CommandError {
     pub fn to_section_report(self) -> eyre::Report {
         match &self {
             CommandError::NonZeroExitCode { stderr, stdout, .. } => {
-                let stderr = String::from_utf8_lossy(stderr).trim().to_string();
-                let stdout = String::from_utf8_lossy(stdout).trim().to_string();
+                let stderr = String::from_utf8_lossy(stderr).trim().to_owned();
+                let stdout = String::from_utf8_lossy(stdout).trim().to_owned();
                 eyre::eyre!(self)
                     .section(color_eyre::SectionExt::header(stderr, "Stderr:"))
                     .section(color_eyre::SectionExt::header(stdout, "Stdout:"))
diff --git a/src/extensions.rs b/src/extensions.rs
index 85be3c7..1afa5b4 100644
--- a/src/extensions.rs
+++ b/src/extensions.rs
@@ -112,7 +112,7 @@ impl CommandExt for Command {
             Err(CommandError::NonZeroExitCode {
                 status,
                 command: self
-                    .command_pretty(msg_info, |ref cmd| STRIPPED_BINS.iter().any(|f| f == cmd)),
+                    .command_pretty(msg_info, |cmd| STRIPPED_BINS.iter().any(|f| f == &cmd)),
                 stderr: output.map(|out| out.stderr.clone()).unwrap_or_default(),
                 stdout: output.map(|out| out.stdout.clone()).unwrap_or_default(),
             })
@@ -140,7 +140,7 @@ impl CommandExt for Command {
             .map_err(|e| CommandError::CouldNotExecute {
                 source: Box::new(e),
                 command: self
-                    .command_pretty(msg_info, |ref cmd| STRIPPED_BINS.iter().any(|f| f == cmd)),
+                    .command_pretty(msg_info, |cmd| STRIPPED_BINS.iter().any(|f| f == &cmd)),
             })
             .map_err(Into::into)
     }
@@ -164,7 +164,7 @@ impl CommandExt for Command {
             CommandError::CouldNotExecute {
                 source: Box::new(e),
                 command: self
-                    .command_pretty(msg_info, |ref cmd| STRIPPED_BINS.iter().any(|f| f == cmd)),
+                    .command_pretty(msg_info, |cmd| STRIPPED_BINS.iter().any(|f| f == &cmd)),
             }
             .to_section_report()
         })
@@ -242,5 +242,5 @@ impl From<SafeCommand> for Command {
 pub(crate) fn env_program(envvar: &str, program: &str) -> String {
     std::env::var(envvar)
         .ok()
-        .unwrap_or_else(|| program.to_string())
+        .unwrap_or_else(|| program.to_owned())
 }
diff --git a/src/file.rs b/src/file.rs
index a81bfcd..c2c976c 100644
--- a/src/file.rs
+++ b/src/file.rs
@@ -77,7 +77,7 @@ impl PathExt for Path {
                     Component::Prefix(prefix) => {
                         eyre::bail!("unix paths cannot handle windows prefix {prefix:?}.")
                     }
-                    Component::RootDir => output = "/".to_string(),
+                    Component::RootDir => output = "/".to_owned(),
                     Component::CurDir => push(&mut output, "."),
                     Component::ParentDir => push(&mut output, ".."),
                     Component::Normal(path) => push(&mut output, path.to_utf8()?),
@@ -85,7 +85,7 @@ impl PathExt for Path {
             }
             Ok(output)
         } else {
-            self.to_utf8().map(|x| x.to_string())
+            self.to_utf8().map(|x| x.to_owned())
         }
     }
 
@@ -109,13 +109,13 @@ impl PathExt for Path {
             match component {
                 Component::Prefix(prefix) => {
                     root_prefix = match prefix.kind() {
-                        Prefix::Verbatim(verbatim) => verbatim.to_utf8()?.to_string(),
+                        Prefix::Verbatim(verbatim) => verbatim.to_utf8()?.to_owned(),
                         Prefix::VerbatimUNC(server, volume) => fmt_unc(server, volume)?,
                         // we should never get this, but it's effectively just
                         // a root_prefix since we force absolute paths.
                         Prefix::VerbatimDisk(disk) => fmt_disk(disk),
                         Prefix::UNC(server, volume) => fmt_unc(server, volume)?,
-                        Prefix::DeviceNS(ns) => ns.to_utf8()?.to_string(),
+                        Prefix::DeviceNS(ns) => ns.to_utf8()?.to_owned(),
                         Prefix::Disk(disk) => fmt_disk(disk),
                     }
                 }
@@ -212,10 +212,12 @@ pub fn shell_escape(string: &str) -> Cow<'_, str> {
     }
 }
 
+#[must_use]
 pub fn maybe_canonicalize(path: &Path) -> Cow<'_, OsStr> {
-    canonicalize(path)
-        .map(|p| Cow::Owned(p.as_os_str().to_owned()))
-        .unwrap_or_else(|_| path.as_os_str().into())
+    canonicalize(path).map_or_else(
+        |_| path.as_os_str().into(),
+        |p| Cow::Owned(p.as_os_str().to_owned()),
+    )
 }
 
 pub fn write_file(path: impl AsRef<Path>, overwrite: bool) -> Result<File> {
@@ -260,13 +262,10 @@ mod tests {
 
     #[test]
     fn as_posix() {
-        result_eq(p!(".").join("..").as_posix(), Ok("./..".to_string()));
-        result_eq(p!(".").join("/").as_posix(), Ok("/".to_string()));
-        result_eq(p!("foo").join("bar").as_posix(), Ok("foo/bar".to_string()));
-        result_eq(
-            p!("/foo").join("bar").as_posix(),
-            Ok("/foo/bar".to_string()),
-        );
+        result_eq(p!(".").join("..").as_posix(), Ok("./..".to_owned()));
+        result_eq(p!(".").join("/").as_posix(), Ok("/".to_owned()));
+        result_eq(p!("foo").join("bar").as_posix(), Ok("foo/bar".to_owned()));
+        result_eq(p!("/foo").join("bar").as_posix(), Ok("/foo/bar".to_owned()));
     }
 
     #[test]
@@ -279,16 +278,16 @@ mod tests {
     #[test]
     #[cfg(target_family = "windows")]
     fn as_wslpath() {
-        result_eq(p!(r"C:\").as_wslpath(), Ok("/mnt/c".to_string()));
-        result_eq(p!(r"C:\Users").as_wslpath(), Ok("/mnt/c/Users".to_string()));
+        result_eq(p!(r"C:\").as_wslpath(), Ok("/mnt/c".to_owned()));
+        result_eq(p!(r"C:\Users").as_wslpath(), Ok("/mnt/c/Users".to_owned()));
         result_eq(
             p!(r"\\localhost\c$\Users").as_wslpath(),
-            Ok("/mnt/c/Users".to_string()),
+            Ok("/mnt/c/Users".to_owned()),
         );
-        result_eq(p!(r"\\.\C:\").as_wslpath(), Ok("/mnt/c".to_string()));
+        result_eq(p!(r"\\.\C:\").as_wslpath(), Ok("/mnt/c".to_owned()));
         result_eq(
             p!(r"\\.\C:\Users").as_wslpath(),
-            Ok("/mnt/c/Users".to_string()),
+            Ok("/mnt/c/Users".to_owned()),
         );
     }
 
@@ -297,24 +296,24 @@ mod tests {
     fn pretty_path_windows() {
         assert_eq!(
             pretty_path("C:\\path\\bin\\cargo.exe", |f| f.contains("cargo")),
-            "cargo".to_string()
+            "cargo".to_owned()
         );
         assert_eq!(
             pretty_path("C:\\Program Files\\Docker\\bin\\docker.exe", |_| false),
-            "\"C:\\Program Files\\Docker\\bin\\docker.exe\"".to_string()
+            "\"C:\\Program Files\\Docker\\bin\\docker.exe\"".to_owned()
         );
         assert_eq!(
             pretty_path("C:\\Program Files\\single'quote\\cargo.exe", |c| c
                 .contains("cargo")),
-            "cargo".to_string()
+            "cargo".to_owned()
         );
         assert_eq!(
             pretty_path("C:\\Program Files\\single'quote\\cargo.exe", |_| false),
-            "\"C:\\Program Files\\single'quote\\cargo.exe\"".to_string()
+            "\"C:\\Program Files\\single'quote\\cargo.exe\"".to_owned()
         );
         assert_eq!(
             pretty_path("C:\\Program Files\\%not_var%\\cargo.exe", |_| false),
-            "\"C:\\\\Program Files\\\\%not_var%\\\\cargo.exe\"".to_string()
+            "\"C:\\\\Program Files\\\\%not_var%\\\\cargo.exe\"".to_owned()
         );
     }
 
@@ -323,19 +322,19 @@ mod tests {
     fn pretty_path_linux() {
         assert_eq!(
             pretty_path("/usr/bin/cargo", |f| f.contains("cargo")),
-            "cargo".to_string()
+            "cargo".to_owned()
         );
         assert_eq!(
             pretty_path("/home/user/my rust/bin/cargo", |_| false),
-            "\"/home/user/my rust/bin/cargo\"".to_string(),
+            "\"/home/user/my rust/bin/cargo\"".to_owned(),
         );
         assert_eq!(
             pretty_path("/home/user/single'quote/cargo", |c| c.contains("cargo")),
-            "cargo".to_string()
+            "cargo".to_owned()
         );
         assert_eq!(
             pretty_path("/home/user/single'quote/cargo", |_| false),
-            "\"/home/user/single'quote/cargo\"".to_string()
+            "\"/home/user/single'quote/cargo\"".to_owned()
         );
     }
 }
diff --git a/src/id.rs b/src/id.rs
index 48022b4..d1cd6dd 100644
--- a/src/id.rs
+++ b/src/id.rs
@@ -2,11 +2,12 @@
 use nix::{
     errno::{errno, Errno},
     unistd::{Gid, Uid},
-    Error,
 };
 #[cfg(not(target_os = "windows"))]
 use std::ffi::CStr;
 
+use crate::errors::*;
+
 #[cfg(target_os = "windows")]
 pub fn group() -> u32 {
     1000
@@ -28,7 +29,7 @@ pub fn user() -> u32 {
 }
 
 #[cfg(target_os = "windows")]
-pub fn username() -> Result<Option<String>, String> {
+pub fn username() -> Result<Option<String>> {
     use std::ptr;
 
     use winapi::um::winbase::GetUserNameW;
@@ -44,7 +45,7 @@ pub fn username() -> Result<Option<String>, String> {
         let mut username = Vec::with_capacity(size as usize);
 
         if GetUserNameW(username.as_mut_ptr(), &mut size) == 0 {
-            return Err("Could not get UserName.".to_owned());
+            eyre::bail!("Could not get UserName.");
         }
 
         // Remove null terminator.
@@ -55,7 +56,7 @@ pub fn username() -> Result<Option<String>, String> {
 }
 
 #[cfg(not(target_os = "windows"))]
-pub fn username() -> Result<Option<String>, Error> {
+pub fn username() -> Result<Option<String>> {
     let name = unsafe {
         Errno::clear();
 
@@ -68,7 +69,7 @@ pub fn username() -> Result<Option<String>, Error> {
                 return Ok(None);
             }
 
-            return Err(Errno::from_i32(errno));
+            return Err(Errno::from_i32(errno)).wrap_err("could not get username");
         }
 
         CStr::from_ptr((*passwd).pw_name)
diff --git a/src/lib.rs b/src/lib.rs
index 1f5c946..57fdcc4 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -13,6 +13,19 @@
 //! </p>
 
 #![deny(missing_debug_implementations, rust_2018_idioms)]
+#![warn(
+    clippy::explicit_into_iter_loop,
+    clippy::explicit_iter_loop,
+    clippy::implicit_clone,
+    clippy::inefficient_to_string,
+    clippy::map_err_ignore,
+    clippy::map_unwrap_or,
+    clippy::ref_binding_to_reference,
+    clippy::semicolon_if_nothing_returned,
+    clippy::str_to_string,
+    clippy::string_to_string,
+    // needs clippy 1.61 clippy::unwrap_used
+)]
 
 #[cfg(test)]
 mod tests;
@@ -92,15 +105,15 @@ impl Host {
             // variable `CROSS_COMPATIBILITY_VERSION`.
             Ok("0.2.1") => match self {
                 Host::X86_64AppleDarwin | Host::Aarch64AppleDarwin => {
-                    target.map(|t| t.needs_docker()).unwrap_or(false)
+                    target.map_or(false, |t| t.needs_docker())
                 }
                 Host::X86_64UnknownLinuxGnu
                 | Host::Aarch64UnknownLinuxGnu
                 | Host::X86_64UnknownLinuxMusl
-                | Host::Aarch64UnknownLinuxMusl => target.map(|t| t.needs_docker()).unwrap_or(true),
-                Host::X86_64PcWindowsMsvc => target
-                    .map(|t| t.triple() != Host::X86_64PcWindowsMsvc.triple() && t.needs_docker())
-                    .unwrap_or(false),
+                | Host::Aarch64UnknownLinuxMusl => target.map_or(true, |t| t.needs_docker()),
+                Host::X86_64PcWindowsMsvc => target.map_or(false, |t| {
+                    t.triple() != Host::X86_64PcWindowsMsvc.triple() && t.needs_docker()
+                }),
                 Host::Other(_) => false,
             },
             // New behaviour, if a target is provided (--target ...) then always run with docker
@@ -113,7 +126,7 @@ impl Host {
             // example to test custom docker images. Cross should not try to recognize if host and
             // target are equal, it's a user decision and if user want's to bypass cross he can call
             // cargo directly or omit the `--target` option.
-            _ => target.map(|t| t.needs_docker()).unwrap_or(false),
+            _ => target.map_or(false, |t| t.needs_docker()),
         }
     }
 
@@ -142,7 +155,7 @@ impl<'a> From<&'a str> for Host {
             "aarch64-apple-darwin" => Host::Aarch64AppleDarwin,
             "aarch64-unknown-linux-gnu" => Host::Aarch64UnknownLinuxGnu,
             "aarch64-unknown-linux-musl" => Host::Aarch64UnknownLinuxMusl,
-            s => Host::Other(s.to_string()),
+            s => Host::Other(s.to_owned()),
         }
     }
 }
@@ -338,7 +351,8 @@ impl From<Host> for Target {
             Host::Aarch64UnknownLinuxMusl => Target::new_built_in("aarch64-unknown-linux-musl"),
             Host::Other(s) => Target::from(
                 s.as_str(),
-                &rustc::target_list(&mut Verbosity::Quiet.into()).unwrap(),
+                &rustc::target_list(&mut Verbosity::Quiet.into())
+                    .expect("should be able to query rustc"),
             ),
         }
     }
@@ -455,20 +469,14 @@ pub fn run() -> Result<ExitStatus> {
                 } else if !rustup::component_is_installed("rust-src", &toolchain, &mut msg_info)? {
                     rustup::install_component("rust-src", &toolchain, &mut msg_info)?;
                 }
-                if args
-                    .subcommand
-                    .map(|sc| sc == Subcommand::Clippy)
-                    .unwrap_or(false)
+                if args.subcommand.map_or(false, |sc| sc == Subcommand::Clippy)
                     && !rustup::component_is_installed("clippy", &toolchain, &mut msg_info)?
                 {
                     rustup::install_component("clippy", &toolchain, &mut msg_info)?;
                 }
             }
 
-            let needs_interpreter = args
-                .subcommand
-                .map(|sc| sc.needs_interpreter())
-                .unwrap_or(false);
+            let needs_interpreter = args.subcommand.map_or(false, |sc| sc.needs_interpreter());
 
             let mut filtered_args = if args
                 .subcommand
@@ -482,36 +490,32 @@ pub fn run() -> Result<ExitStatus> {
                     } else if arg.starts_with("--target=") {
                         // NOOP
                     } else {
-                        filtered_args.push(arg)
+                        filtered_args.push(arg);
                     }
                 }
                 filtered_args
             // Make sure --target is present
             } else if !args.all.iter().any(|a| a.starts_with("--target")) {
                 let mut args_with_target = args.all.clone();
-                args_with_target.push("--target".to_string());
-                args_with_target.push(target.triple().to_string());
+                args_with_target.push("--target".to_owned());
+                args_with_target.push(target.triple().to_owned());
                 args_with_target
             } else {
                 args.all.clone()
             };
 
-            let is_test = args
-                .subcommand
-                .map(|sc| sc == Subcommand::Test)
-                .unwrap_or(false);
+            let is_test = args.subcommand.map_or(false, |sc| sc == Subcommand::Test);
             if is_test && config.doctests().unwrap_or_default() && is_nightly {
-                filtered_args.push("-Zdoctest-xcompile".to_string());
+                filtered_args.push("-Zdoctest-xcompile".to_owned());
             }
             if uses_build_std {
-                filtered_args.push("-Zbuild-std".to_string());
+                filtered_args.push("-Zbuild-std".to_owned());
             }
 
             let is_remote = docker::Engine::is_remote();
             let needs_docker = args
                 .subcommand
-                .map(|sc| sc.needs_docker(is_remote))
-                .unwrap_or(false);
+                .map_or(false, |sc| sc.needs_docker(is_remote));
             if target.needs_docker() && needs_docker {
                 let engine = docker::Engine::new(None, Some(is_remote), &mut msg_info)?;
                 if host_version_meta.needs_interpreter()
@@ -519,7 +523,7 @@ pub fn run() -> Result<ExitStatus> {
                     && target.needs_interpreter()
                     && !interpreter::is_registered(&target)?
                 {
-                    docker::register(&engine, &target, &mut msg_info)?
+                    docker::register(&engine, &target, &mut msg_info)?;
                 }
 
                 let paths = docker::DockerPaths::create(&engine, metadata, cwd, sysroot)?;
@@ -527,10 +531,7 @@ pub fn run() -> Result<ExitStatus> {
                     docker::DockerOptions::new(engine, target.clone(), config, uses_xargo);
                 let status = docker::run(options, paths, &filtered_args, &mut msg_info)
                     .wrap_err("could not run container")?;
-                let needs_host = args
-                    .subcommand
-                    .map(|sc| sc.needs_host(is_remote))
-                    .unwrap_or(false);
+                let needs_host = args.subcommand.map_or(false, |sc| sc.needs_host(is_remote));
                 if !status.success() {
                     warn_on_failure(&target, &toolchain, &mut msg_info)?;
                 }
@@ -554,7 +555,7 @@ pub fn run() -> Result<ExitStatus> {
             } else {
                 // Not a list subcommand, which can happen with weird edge-cases.
                 print!("{}", stdout);
-                io::stdout().flush().unwrap();
+                io::stdout().flush().expect("could not flush");
             }
             Ok(out.status)
         }
diff --git a/src/rustc.rs b/src/rustc.rs
index a68fd26..5b9a424 100644
--- a/src/rustc.rs
+++ b/src/rustc.rs
@@ -14,6 +14,7 @@ pub struct TargetList {
 }
 
 impl TargetList {
+    #[must_use]
     pub fn contains(&self, triple: &str) -> bool {
         self.triples.iter().any(|t| t == triple)
     }
@@ -35,10 +36,10 @@ impl VersionMetaExt for VersionMeta {
     }
 
     fn commit_hash(&self) -> String {
-        self.commit_hash
-            .as_ref()
-            .map(|x| short_commit_hash(x))
-            .unwrap_or_else(|| hash_from_version_string(&self.short_version_string, 2))
+        self.commit_hash.as_ref().map_or_else(
+            || hash_from_version_string(&self.short_version_string, 2),
+            |x| short_commit_hash(x),
+        )
     }
 }
 
@@ -49,9 +50,10 @@ fn short_commit_hash(hash: &str) -> String {
 
     hash.get(..LENGTH)
         .unwrap_or_else(|| panic!("commit hash must be at least {LENGTH} characters long"))
-        .to_string()
+        .to_owned()
 }
 
+#[must_use]
 pub fn hash_from_version_string(version: &str, index: usize) -> String {
     let is_hash = |x: &str| x.chars().all(|c| c.is_ascii_hexdigit());
     let is_date = |x: &str| x.chars().all(|c| matches!(c, '-' | '0'..='9'));
@@ -77,6 +79,7 @@ pub fn hash_from_version_string(version: &str, index: usize) -> String {
     short_commit_hash(&const_sha1::sha1(&buffer).to_string())
 }
 
+#[must_use]
 pub fn rustc_command() -> Command {
     Command::new(env_program("RUSTC", "rustc"))
 }
@@ -124,7 +127,7 @@ pub fn get_sysroot(
             .collect::<Vec<_>>()
             .join("-")
     } else {
-        default_toolchain.to_string()
+        default_toolchain.to_owned()
     };
     sysroot.set_file_name(&toolchain);
 
diff --git a/src/rustup.rs b/src/rustup.rs
index f04fd07..a13b1da 100644
--- a/src/rustup.rs
+++ b/src/rustup.rs
@@ -82,14 +82,18 @@ pub fn available_targets(toolchain: &str, msg_info: &mut MessageInfo) -> Result<
     let mut not_installed = vec![];
 
     for line in out.lines() {
-        let target = line.split(' ').next().unwrap().to_string();
+        let target = line
+            .split(' ')
+            .next()
+            .expect("rustup output should be consistent")
+            .to_owned();
         if line.contains("(default)") {
             assert!(default.is_empty());
             default = target;
         } else if line.contains("(installed)") {
-            installed.push(target)
+            installed.push(target);
         } else {
-            not_installed.push(target)
+            not_installed.push(target);
         }
     }
 
@@ -160,11 +164,13 @@ pub fn check_component<'a>(
                 false => None,
             }
         })
-        .map(|installed| match installed {
-            true => Component::Installed(component),
-            false => Component::Available(component),
-        })
-        .unwrap_or_else(|| Component::NotAvailable(component)))
+        .map_or_else(
+            || Component::NotAvailable(component),
+            |installed| match installed {
+                true => Component::Installed(component),
+                false => Component::Available(component),
+            },
+        ))
 }
 
 pub fn component_is_installed(
@@ -176,7 +182,12 @@ pub fn component_is_installed(
 }
 
 fn rustc_channel(version: &Version) -> Result<Channel> {
-    match version.pre.split('.').next().unwrap() {
+    match version
+        .pre
+        .split('.')
+        .next()
+        .expect("rust prerelease version should contain `.`")
+    {
         "" => Ok(Channel::Stable),
         "dev" => Ok(Channel::Dev),
         "beta" => Ok(Channel::Beta),
@@ -200,7 +211,7 @@ pub fn rustc_version_string(toolchain_path: &Path) -> Result<Option<String>> {
             .and_then(|pkg| pkg.get("rust"))
             .and_then(|rust| rust.get("version"))
             .and_then(|version| version.as_str())
-            .map(|version| version.to_string()));
+            .map(|version| version.to_owned()));
     }
     Ok(None)
 }
diff --git a/src/shell.rs b/src/shell.rs
index 3805b00..3978d91 100644
--- a/src/shell.rs
+++ b/src/shell.rs
@@ -121,6 +121,7 @@ impl MessageInfo {
         })
     }
 
+    #[must_use]
     pub fn is_verbose(&self) -> bool {
         self.verbosity.verbose()
     }
@@ -169,7 +170,8 @@ impl MessageInfo {
 
     /// prints a red 'error' message and terminates.
     pub fn fatal<T: fmt::Display>(&mut self, message: T, code: i32) -> ! {
-        self.error(message).unwrap();
+        self.error(message)
+            .expect("could not display fatal message");
         std::process::exit(code);
     }
 
@@ -240,7 +242,8 @@ impl MessageInfo {
     }
 
     pub fn fatal_usage<T: fmt::Display>(&mut self, arg: T, code: i32) -> ! {
-        self.error_usage(arg).unwrap();
+        self.error_usage(arg)
+            .expect("could not display usage message");
         std::process::exit(code);
     }
 
@@ -319,6 +322,7 @@ pub trait Stream {
     const TTY: atty::Stream;
     const OWO: owo_colors::Stream;
 
+    #[must_use]
     fn is_atty() -> bool {
         atty::is(Self::TTY)
     }
@@ -347,6 +351,7 @@ pub fn default_ident() -> usize {
     cross_prefix!("").len()
 }
 
+#[must_use]
 pub fn indent(message: &str, spaces: usize) -> String {
     message
         .lines()
diff --git a/src/temp.rs b/src/temp.rs
index 12f24ac..f9a180d 100644
--- a/src/temp.rs
+++ b/src/temp.rs
@@ -39,7 +39,7 @@ unsafe fn push_tempfile() -> Result<&'static mut tempfile::NamedTempFile> {
     fs::create_dir_all(&parent).ok();
     let file = tempfile::NamedTempFile::new_in(&parent)?;
     FILES.push(file);
-    Ok(FILES.last_mut().unwrap())
+    Ok(FILES.last_mut().expect("file list should not be empty"))
 }
 
 /// # Safety
@@ -66,6 +66,7 @@ impl TempFile {
         self.file
     }
 
+    #[must_use]
     pub fn path(&self) -> &Path {
         self.file.path()
     }
@@ -87,7 +88,7 @@ unsafe fn push_tempdir() -> Result<&'static Path> {
     fs::create_dir_all(&parent).ok();
     let dir = tempfile::TempDir::new_in(&parent)?;
     DIRS.push(dir);
-    Ok(DIRS.last().unwrap().path())
+    Ok(DIRS.last().expect("should not be empty").path())
 }
 
 /// # Safety
@@ -110,6 +111,7 @@ impl TempDir {
         })
     }
 
+    #[must_use]
     pub fn path(&self) -> &'static Path {
         self.path
     }


Test patch:
diff --git a/src/tests.rs b/src/tests.rs
index 23067fb..16f2436 100644
--- a/src/tests.rs
+++ b/src/tests.rs
@@ -14,6 +14,7 @@ static WORKSPACE: OnceCell<PathBuf> = OnceCell::new();
 pub fn get_cargo_workspace() -> &'static Path {
     let manifest_dir = env!("CARGO_MANIFEST_DIR");
     let mut msg_info = crate::shell::Verbosity::Verbose.into();
+    #[allow(clippy::unwrap_used)]
     WORKSPACE.get_or_init(|| {
         crate::cargo_metadata_with_args(Some(manifest_dir.as_ref()), None, &mut msg_info)
             .unwrap()
diff --git a/src/tests/toml.rs b/src/tests/toml.rs
index 5dac790..d917ea9 100644
--- a/src/tests/toml.rs
+++ b/src/tests/toml.rs
@@ -10,7 +10,7 @@ static TOML_REGEX: Lazy<Regex> = Lazy::new(|| {
         .multi_line(true)
         .dot_matches_new_line(true)
         .build()
-        .unwrap()
+        .expect("regex should be valid")
 });
 
 #[test]