rewriting rust with coccinelle

https://twitter.com/josh_triplett/status/994753065478582272

https://github.com/rust-lang/rust-analyzer/issues/3186 https://www.google.com/search?channel=fs&client=ubuntu-sn&q=site%3Agithub.com++rust+semantic+patch+-semver

https://gitlab.inria.fr/coccinelle/coccinelleforrust

https://www.youtube.com/watch?v=Gh9lOyddqbY

https://users.rust-lang.org/t/we-need-a-great-general-refactoring-tool/103985/13

ohwow https://gitlab.inria.fr/lawall/patchparse4

suggest better collection given apparent use

Notice an iterator looking into another one If it’s doing things a certain special way Suggest a set impl so O(n) --> O(1)

 /// List FDB entries that are the result of a replication (i.e. on a veth)
 pub async fn list_replicated_macs(rtnl: &Netlink, links: &LinkMap) -> Result<Vec<FdbReplicated>> {
+    let link_macs = links.values().map(|link| link.mac).collect::<HashSet<_>>();
     let neighs = rtnl.get_bridge_neighs().await?;

     let neighs = neighs.into_iter().filter_map(|neigh| {
         // Ensure the neigh has a VLAN (or not, we don't care, it's just to deduplicate the neigh)
         neigh.vlan?;
         // Ignore MAC if it's the one of an interface itself
-        if links.values().any(|link| link.mac.as_slice() == neigh.mac) {
+        if link_macs.contains(&neigh.mac) {
             return None;
         }
         // Ignore multicast neighbors
         if neigh.is_multicast() {
             return None;
         }

         match links.get(&neigh.ifindex) {
             Some(Link::Veth(veth)) if veth.base.master.is_some() => {
                 Some((veth.base.index, neigh.mac))
             }
             _ => None,
         }
     });

     Ok(neighs.collect())
}
pub async fn list_replicated_macs(rtnl: &Netlink, links: &LinkMap) -> Result<Vec<FdbReplicated>> {
    // +    let link_macs = links.values().map(|link| link.mac).collect::<HashSet<_>>();
    let neighs = rtnl.get_bridge_neighs().await?;

    let neighs = neighs.into_iter().filter_map(|neigh| {
        // Ensure the neigh has a VLAN (or not, we don't care, it's just to deduplicate the neigh)
        neigh.vlan?;
        // Ignore MAC if it's the one of an interface itself
        if links.values().any(|link| link.mac.as_slice() == neigh.mac) {
            // +        if link_macs.contains(&neigh.mac) {
            return None;
        }
        // Ignore multicast neighbors
        if neigh.is_multicast() {
            return None;
        }

        match links.get(&neigh.ifindex) {
            Some(Link::Veth(veth)) if veth.base.master.is_some() => {
                Some((veth.base.index, neigh.mac))
            }
            _ => None,
        }
    });

    Ok(neighs.collect())
}

Attempt #1

@@
identifier c;
expression a, b, d;
@@

-    let a = b;
+    let a = b.iter().collect::<::std::collections::HashSet<_>>();

     ...

     for c in d {
         ...

-        if a.any(|x| x == c) {
+        if a.contains(&c) {
             ...
         }

         ...
     }

Attempt #2

cargo run --locked --frozen --offline --release -- --coccifile should_be_using_hashset.cocci src/should_be_using_hashset.rs
./target/release/cfr --coccifile should_be_using_hashset.cocci src/should_be_using_hashset.rs
@@
identifier xs, x, c;
expression items;
Iterator it;
@@

     let xs =
-             items;
+             items.iter().collect::<HashSet<_>>();

     ...

     it.filter_map(|x| {
         ...

         if xs.
-              any(|c| c == x)
+              contains(&x)
         {
             ...
         }

         ...
     })

#[test]
fn collecting_needlessly() {
    use std::collections::HashMap;

    let hmap = HashMap::from([('a', 42)]);
    for item in hmap.keys().copied().collect::<Vec<_>>() { // <--
        let _ = item;
    }
}
// cargo run --locked --frozen --offline --release -- --no-parallel --coccifile src/tests/needless_collect.cocci src/tests/needless_collect.rs

@@
Iterator it;
identifier x;
@@

     for x in it
-                 .copied().collect::<Vec<_>>()
     {
         ...
     }