Skip to content

Commit 241333d

Browse files
pnkfelixpietroalbini
authored andcommitted
Regression test for issue.
1 parent 49e7b5c commit 241333d

3 files changed

+88
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0597]: `line` does not live long enough
2+
--> $DIR/issue-52126-assign-op-invariance.rs:44:28
3+
|
4+
LL | let v: Vec<&str> = line.split_whitespace().collect();
5+
| ^^^^ borrowed value does not live long enough
6+
LL | //~^ ERROR `line` does not live long enough
7+
LL | println!("accumulator before add_assign {:?}", acc.map);
8+
| ------- borrow later used here
9+
...
10+
LL | }
11+
| - borrowed value only lives until here
12+
13+
error: aborting due to previous error
14+
15+
For more information about this error, try `rustc --explain E0597`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Issue 52126: With respect to variance, the assign-op's like += were
12+
// accidentally lumped together with other binary op's. In both cases
13+
// we were coercing the LHS of the op to the expected supertype.
14+
//
15+
// The problem is that since the LHS of += is modified, we need the
16+
// parameter to be invariant with respect to the overall type, not
17+
// covariant.
18+
19+
use std::collections::HashMap;
20+
use std::ops::AddAssign;
21+
22+
pub fn main() {
23+
panics();
24+
}
25+
26+
pub struct Counter<'l> {
27+
map: HashMap<&'l str, usize>,
28+
}
29+
30+
impl<'l> AddAssign for Counter<'l>
31+
{
32+
fn add_assign(&mut self, rhs: Counter<'l>) {
33+
rhs.map.into_iter().for_each(|(key, val)| {
34+
let count = self.map.entry(key).or_insert(0);
35+
*count += val;
36+
});
37+
}
38+
}
39+
40+
/// often times crashes, if not prints invalid strings
41+
pub fn panics() {
42+
let mut acc = Counter{map: HashMap::new()};
43+
for line in vec!["123456789".to_string(), "12345678".to_string()] {
44+
let v: Vec<&str> = line.split_whitespace().collect();
45+
//~^ ERROR `line` does not live long enough
46+
println!("accumulator before add_assign {:?}", acc.map);
47+
let mut map = HashMap::new();
48+
for str_ref in v {
49+
let e = map.entry(str_ref);
50+
println!("entry: {:?}", e);
51+
let count = e.or_insert(0);
52+
*count += 1;
53+
}
54+
let cnt2 = Counter{map};
55+
acc += cnt2;
56+
println!("accumulator after add_assign {:?}", acc.map);
57+
// line gets dropped here but references are kept in acc.map
58+
}
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0597]: `line` does not live long enough
2+
--> $DIR/issue-52126-assign-op-invariance.rs:44:28
3+
|
4+
LL | let v: Vec<&str> = line.split_whitespace().collect();
5+
| ^^^^ borrowed value does not live long enough
6+
...
7+
LL | }
8+
| - `line` dropped here while still borrowed
9+
LL | }
10+
| - borrowed value needs to live until here
11+
12+
error: aborting due to previous error
13+
14+
For more information about this error, try `rustc --explain E0597`.

0 commit comments

Comments
 (0)