]> git.lizzy.rs Git - rust.git/blob - src/test/ui/issues/issue-52126-assign-op-invariance.rs
Rollup merge of #62337 - Mark-Simulacrum:fix-cpu-usage-script, r=alexcrichton
[rust.git] / src / test / ui / issues / issue-52126-assign-op-invariance.rs
1 // Issue 52126: With respect to variance, the assign-op's like += were
2 // accidentally lumped together with other binary op's. In both cases
3 // we were coercing the LHS of the op to the expected supertype.
4 //
5 // The problem is that since the LHS of += is modified, we need the
6 // parameter to be invariant with respect to the overall type, not
7 // covariant.
8
9 use std::collections::HashMap;
10 use std::ops::AddAssign;
11
12 pub fn main() {
13     panics();
14 }
15
16 pub struct Counter<'l> {
17     map: HashMap<&'l str, usize>,
18 }
19
20 impl<'l> AddAssign for Counter<'l>
21 {
22     fn add_assign(&mut self, rhs: Counter<'l>) {
23         rhs.map.into_iter().for_each(|(key, val)| {
24             let count = self.map.entry(key).or_insert(0);
25             *count += val;
26         });
27     }
28 }
29
30 /// Often crashes, if not prints invalid strings.
31 pub fn panics() {
32     let mut acc = Counter{map: HashMap::new()};
33     for line in vec!["123456789".to_string(), "12345678".to_string()] {
34         let v: Vec<&str> = line.split_whitespace().collect();
35         //~^ ERROR `line` does not live long enough
36         // println!("accumulator before add_assign {:?}", acc.map);
37         let mut map = HashMap::new();
38         for str_ref in v {
39             let e = map.entry(str_ref);
40             println!("entry: {:?}", e);
41             let count = e.or_insert(0);
42             *count += 1;
43         }
44         let cnt2 = Counter{map};
45         acc += cnt2;
46         // println!("accumulator after add_assign {:?}", acc.map);
47         // line gets dropped here but references are kept in acc.map
48     }
49 }