1// run-rustfix
2
3#![allow(unused, clippy::needless_pass_by_value, clippy::collapsible_if)]
4#![warn(clippy::map_entry)]
5#![feature(asm)]
6
7use std::collections::HashMap;
8use std::hash::Hash;
9
10macro_rules! m {
11    ($e:expr) => {{ $e }};
12}
13
14macro_rules! insert {
15    ($map:expr, $key:expr, $val:expr) => {
16        $map.insert($key, $val)
17    };
18}
19
20fn foo() {}
21
22fn hash_map<K: Eq + Hash + Copy, V: Copy>(m: &mut HashMap<K, V>, m2: &mut HashMap<K, V>, k: K, k2: K, v: V, v2: V) {
23    // or_insert(v)
24    m.entry(k).or_insert(v);
25
26    // semicolon on insert, use or_insert_with(..)
27    m.entry(k).or_insert_with(|| {
28        if true {
29            v
30        } else {
31            v2
32        }
33    });
34
35    // semicolon on if, use or_insert_with(..)
36    m.entry(k).or_insert_with(|| {
37        if true {
38            v
39        } else {
40            v2
41        }
42    });
43
44    // early return, use if let
45    if let std::collections::hash_map::Entry::Vacant(e) = m.entry(k) {
46        if true {
47            e.insert(v);
48        } else {
49            e.insert(v2);
50            return;
51        }
52    }
53
54    // use or_insert_with(..)
55    m.entry(k).or_insert_with(|| {
56        foo();
57        v
58    });
59
60    // semicolon on insert and match, use or_insert_with(..)
61    m.entry(k).or_insert_with(|| {
62        match 0 {
63            1 if true => {
64                v
65            },
66            _ => {
67                v2
68            },
69        }
70    });
71
72    // one branch doesn't insert, use if let
73    if let std::collections::hash_map::Entry::Vacant(e) = m.entry(k) {
74        match 0 {
75            0 => foo(),
76            _ => {
77                e.insert(v2);
78            },
79        };
80    }
81
82    // use or_insert_with
83    m.entry(k).or_insert_with(|| {
84        foo();
85        match 0 {
86            0 if false => {
87                v
88            },
89            1 => {
90                foo();
91                v
92            },
93            2 | 3 => {
94                for _ in 0..2 {
95                    foo();
96                }
97                if true {
98                    v
99                } else {
100                    v2
101                }
102            },
103            _ => {
104                v2
105            },
106        }
107    });
108
109    // ok, insert in loop
110    if !m.contains_key(&k) {
111        for _ in 0..2 {
112            m.insert(k, v);
113        }
114    }
115
116    // macro_expansion test, use or_insert(..)
117    m.entry(m!(k)).or_insert_with(|| m!(v));
118
119    // ok, map used before insertion
120    if !m.contains_key(&k) {
121        let _ = m.len();
122        m.insert(k, v);
123    }
124
125    // ok, inline asm
126    if !m.contains_key(&k) {
127        unsafe { asm!("nop") }
128        m.insert(k, v);
129    }
130
131    // ok, different keys.
132    if !m.contains_key(&k) {
133        m.insert(k2, v);
134    }
135
136    // ok, different maps
137    if !m.contains_key(&k) {
138        m2.insert(k, v);
139    }
140
141    // ok, insert in macro
142    if !m.contains_key(&k) {
143        insert!(m, k, v);
144    }
145
146    // or_insert_with. Partial move of a local declared in the closure is ok.
147    m.entry(k).or_insert_with(|| {
148        let x = (String::new(), String::new());
149        let _ = x.0;
150        v
151    });
152}
153
154fn main() {}
155