]> git.proxmox.com Git - rustc.git/blob - src/test/ui/issues/issue-52126-assign-op-invariance.rs
New upstream version 1.34.2+dfsg1
[rustc.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 }