I think at least //Err after
will compile, but even with Polonius it doesn't.
use std::collections::HashMap;
struct X<'a> {
v: &'a str,
}
struct XS<'a> {
v: &'a str,
s: String,
}
struct MF<'a, 'b> {
fa: &'a str,
fb: &'b str,
fc: String,
fd: String,
}
fn pl() {
println!("-----------------");
}
fn main() {
polonius();
pl();
s();
pl();
s_s();
pl();
x();
pl();
xx();
pl();
xs();
pl();
xs_ok_b();
pl();
m_f();
pl();
m_f_ok_b();
pl();
}
fn s() {
let s = String::from("s");
let s_2 = String::from("s_2");
let s2 = String::from("s2");
let s2_2 = String::from("s2_2");
let s3 = String::from("s3");
let s3_str = "s3_str";
let mut a = &s;
let mut b = &s2;
let mut c = &s3[..];
println!("{:6} {:6} {:6}", a, b, c);
a = &s_2;
drop(s); //Ok after
drop(s2); //Ok before
b = &s2_2;
drop(s3);
c = &s3_str;
println!("{:6} {:6} {:6}", a, b, c);
}
fn s_s() {
let s = String::from("s");
let s_2 = String::from("s_2");
let s2 = String::from("s2");
let s2_2 = String::from("s2_2");
let s3 = String::from("s3");
let s3_str = "s3_str";
let mut a = &s;
let mut b = &s2;
let mut c = &s3[..];
println!("{:6} {:6} {:6}", a, b, c);
*(&mut a) = &s_2;
//drop(s); //Err after
//drop(s2); //Err before
*(&mut b) = &s2_2;
*(&mut c) = &s3_str;
//drop(s3); //Err after
println!("{:6} {:6} {:6}", a, b, c);
}
fn x() {
let x = String::from("x");
let x_2 = String::from("x_2");
let x2 = String::from("x2");
let x2_2 = String::from("x2_2");
let x_str = "x_str";
let mut a = X { v: &x };
let mut b = X { v: &x2 };
println!("{:6} {:6}", a.v, b.v);
a.v = &x_2;
//drop(x); //Err after
//drop(x2); //Err before
b.v = &x2_2;
println!("{:6} {:6}", a.v, b.v);
a.v = &x_str;
//drop(x_2); //Err after
println!("{:6} {:6}", a.v, b.v);
}
fn xx() {
let xx = String::from("xx");
let xx_2 = String::from("xx_2");
let xx2 = String::from("xx2");
let xx2_2 = String::from("xx2_2");
let mut a = X { v: &xx };
let mut b = X { v: &xx2 };
println!("{:6} {:6}", a.v, b.v);
a = X { v: &xx_2 };
drop(xx); //Ok after
drop(xx2); //Ok before
b = X { v: &xx2_2 };
println!("{:6} {:6}", a.v, b.v);
}
fn xs() {
let xs = String::from("xs");
let xs_2 = String::from("xs_2");
let xs2 = String::from("xs2");
let xs2_2 = String::from("xs2_2");
let s = String::from("s");
let s2 = String::from("s2");
let mut a = XS { v: &xs, s };
let mut b = XS { v: &xs2, s: s2 };
println!("{:6} {:6} {:6} {:6}", a.v, a.s, b.v, b.s);
//a = XS { v: &xs_2, s}; //cannot, s has moved into a
//a = XS { v: &xs_2, s: a.s }; //can
a = XS { v: &xs_2, ..a };
drop(xs); //Ok after
//drop(xs2); //Err before
b = XS { v: &xs2_2, ..b };
println!("{:6} {:6} {:6} {:6}", a.v, a.s, b.v, b.s);
}
fn xs_ok_b() {
println!("xs_ok_b");
let xs = String::from("xs");
let xs_2 = String::from("xs_2");
let xs2 = String::from("xs2");
let xs2_2 = String::from("xs2_2");
let s = String::from("s");
let s2 = String::from("s2");
let mut a = XS { v: &xs, s };
let mut b = XS { v: &xs2, s: s2 };
println!("{:6} {:6} {:6} {:6}", a.v, a.s, b.v, b.s);
a = XS { v: &xs_2, ..a };
drop(xs); //Ok after
let s2 = b.s;
drop(xs2); //Ok before
b = XS { v: &xs2_2, s: s2 };
println!("{:6} {:6} {:6} {:6}", a.v, a.s, b.v, b.s);
}
fn m_f() {
let fa = String::from("fa");
let fa_2 = String::from("fa_2");
let fb = String::from("fb");
let fb_2 = String::from("fb_2");
let fc = String::from("fc");
let fd = String::from("fd");
let fa2 = String::from("fa2");
let fa2_2 = String::from("fa2_2");
let fb2 = String::from("fb2");
let fb2_2 = String::from("fb2_2");
let fc2 = String::from("fc2");
let fd2 = String::from("fd2");
let mut a = MF {
fa: &fa,
fb: &fb,
fc,
fd,
};
let mut b = MF {
fa: &fa2,
fb: &fb2,
fc: fc2,
fd: fd2,
};
println!(
"{:6} {:6} {:6} {:6} {:6} {:6} {:6} {:6}",
a.fa, a.fb, a.fc, a.fd, b.fa, b.fb, b.fc, b.fd
);
a = MF {
fa: &fa_2,
fb: &fb_2,
..a
};
drop(fa); //Ok after
drop(fb); //Ok after
//drop(fa2); // Err before
//drop(fb2); // Err before
b = MF {
fa: &fa2_2,
fb: &fb2_2,
..b
};
println!(
"{:6} {:6} {:6} {:6} {:6} {:6} {:6} {:6}",
a.fa, a.fb, a.fc, a.fd, b.fa, b.fb, b.fc, b.fd
);
}
fn m_f_ok_b() {
println!("m_f_ok_b");
let fa = String::from("fa");
let fa_2 = String::from("fa_2");
let fb = String::from("fb");
let fb_2 = String::from("fb_2");
let fc = String::from("fc");
let fd = String::from("fd");
let fa2 = String::from("fa2");
let fa2_2 = String::from("fa2_2");
let fb2 = String::from("fb2");
let fb2_2 = String::from("fb2_2");
let fc2 = String::from("fc2");
let fd2 = String::from("fd2");
let mut a = MF {
fa: &fa,
fb: &fb,
fc,
fd,
};
let mut b = MF {
fa: &fa2,
fb: &fb2,
fc: fc2,
fd: fd2,
};
println!(
"{:6} {:6} {:6} {:6} {:6} {:6} {:6} {:6}",
a.fa, a.fb, a.fc, a.fd, b.fa, b.fb, b.fc, b.fd
);
a = MF {
fa: &fa_2,
fb: &fb_2,
..a
};
drop(fa); //Ok after
drop(fb); //Ok after
let t = (b.fc, b.fd);
drop(fa2); // Ok before
drop(fb2); // Ok before
b = MF {
fa: &fa2_2,
fb: &fb2_2,
fc: t.0,
fd: t.1,
};
println!(
"{:6} {:6} {:6} {:6} {:6} {:6} {:6} {:6}",
a.fa, a.fb, a.fc, a.fd, b.fa, b.fb, b.fc, b.fd
);
}
fn get_or_insert(map: &'_ mut HashMap<u32, String>) -> &'_ String {
if let Some(v) = map.get(&22) {
return v;
}
map.insert(22, String::from("hi, polonius works fine"));
&map[&22]
}
fn polonius() {
let mut map = HashMap::new();
get_or_insert(&mut map);
println!("{}", map.get(&22).unwrap());
}