Skip to content

FP redundant_iter_cloned move || { .. into thread #16012

@matthiaskrgr

Description

@matthiaskrgr

Using the following flags

--force-warn clippy::redundant_iter_cloned

this code:

use std::process::*;
use std::io::*;
use std::path::*;
use std::fs::File;
use std::fs;
use std::thread;

const N: usize = 2;
const M: usize = 100;

fn main() {
    let dirs = (100..N).map(|n| {
        PathBuf::from(format!("dir{}", n))
    }).collect::<Vec<_>>();

    for dir in dirs.iter() {
        fs::create_dir_all(&dir).unwrap();
        File::create(dir.join("main.rs")).unwrap()
            .write_all(b"fn main() {}").unwrap();
    }

    let threads = dirs.iter().cloned().map(|m| {
        thread::spawn(move || {
            for _ in 0..M {
                let mut cmd = Command::new("rustc");
                cmd.current_dir(&m).arg("--crate-name").arg("main.rs");
                println!("{:?}", cmd);
                let status = cmd.status().unwrap();
                assert!(status.success());
            }
        })
    }).collect::<Vec<_>>();

    for thread in threads {
        thread.join().unwrap();
    }
}

caused the following diagnostics:

    Checking _20ec98548bdd3aeeabbebdf65e340ad25eb521c3 v0.1.0 (/tmp/icemaker_global_tempdir.tMrpGeJ6WWUI/icemaker_clippyfix_tempdir.AWKSjHKFWkna/_20ec98548bdd3aeeabbebdf65e340ad25eb521c3)
warning: unneeded cloning of iterator items
  --> src/main.rs:22:19
   |
22 |       let threads = dirs.iter().cloned().map(|m| {
   |  ___________________^
23 | |         thread::spawn(move || {
24 | |             for _ in 0..M {
25 | |                 let mut cmd = Command::new("rustc");
...  |
31 | |         })
32 | |     }).collect::<Vec<_>>();
   | |______^
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_iter_cloned
   = note: requested on the command line with `--force-warn clippy::redundant-iter-cloned`
help: try
   |
22 ~     let threads = dirs.iter().map(|m| {
23 +         thread::spawn(move || {
24 +             for _ in 0..M {
25 +                 let mut cmd = Command::new("rustc");
26 +                 cmd.current_dir(&m).arg("--crate-name").arg("main.rs");
27 +                 println!("{:?}", cmd);
28 +                 let status = cmd.status().unwrap();
29 +                 assert!(status.success());
30 +             }
31 +         })
32 ~     }).collect::<Vec<_>>();
   |

warning: `_20ec98548bdd3aeeabbebdf65e340ad25eb521c3` (bin "_20ec98548bdd3aeeabbebdf65e340ad25eb521c3") generated 1 warning
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.24s

However after applying these diagnostics, the resulting code:

use std::process::*;
use std::io::*;
use std::path::*;
use std::fs::File;
use std::fs;
use std::thread;

const N: usize = 2;
const M: usize = 100;

fn main() {
    let dirs = (100..N).map(|n| {
        PathBuf::from(format!("dir{}", n))
    }).collect::<Vec<_>>();

    for dir in dirs.iter() {
        fs::create_dir_all(&dir).unwrap();
        File::create(dir.join("main.rs")).unwrap()
            .write_all(b"fn main() {}").unwrap();
    }

    let threads = dirs.iter().map(|m| {
        thread::spawn(move || {
            for _ in 0..M {
                let mut cmd = Command::new("rustc");
                cmd.current_dir(&m).arg("--crate-name").arg("main.rs");
                println!("{:?}", cmd);
                let status = cmd.status().unwrap();
                assert!(status.success());
            }
        })
    }).collect::<Vec<_>>();

    for thread in threads {
        thread.join().unwrap();
    }
}

no longer compiled:

    Checking _20ec98548bdd3aeeabbebdf65e340ad25eb521c3 v0.1.0 (/tmp/icemaker_global_tempdir.tMrpGeJ6WWUI/icemaker_clippyfix_tempdir.AWKSjHKFWkna/_20ec98548bdd3aeeabbebdf65e340ad25eb521c3)
error[E0597]: `dirs` does not live long enough
   --> src/main.rs:22:19
    |
 12 |       let dirs = (100..N).map(|n| {
    |           ---- binding `dirs` declared here
...
 22 |       let threads = dirs.iter().map(|m| {
    |                     ^^^^ borrowed value does not live long enough
 23 | /         thread::spawn(move || {
 24 | |             for _ in 0..M {
 25 | |                 let mut cmd = Command::new("rustc");
 26 | |                 cmd.current_dir(&m).arg("--crate-name").arg("main.rs");
...   |
 31 | |         })
    | |__________- argument requires that `dirs` is borrowed for `'static`
...
 37 |   }
    |   - `dirs` dropped here while still borrowed
    |
note: requirement that the value outlives `'static` introduced here
   --> /home/matthias/.rustup/toolchains/master/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:776:12
    |
776 |         F: FnMut(Self::Item) -> B,
    |            ^^^^^^^^^^^^^^^^^^^^^^

For more information about this error, try `rustc --explain E0597`.
error: could not compile `_20ec98548bdd3aeeabbebdf65e340ad25eb521c3` (bin "_20ec98548bdd3aeeabbebdf65e340ad25eb521c3") due to 1 previous error
warning: build failed, waiting for other jobs to finish...
error: could not compile `_20ec98548bdd3aeeabbebdf65e340ad25eb521c3` (bin "_20ec98548bdd3aeeabbebdf65e340ad25eb521c3" test) due to 1 previous error

Version:

rustc 1.93.0-nightly (6a884ad1b 2025-11-02)
binary: rustc
commit-hash: 6a884ad1b502fe48307d363858510702429fc735
commit-date: 2025-11-02
host: x86_64-unknown-linux-gnu
release: 1.93.0-nightly
LLVM version: 21.1.3

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: Clippy is not doing the correct thingI-suggestion-causes-errorIssue: The suggestions provided by this Lint cause an ICE/error when applied

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions