I ran across this in someone else's thread but didn't want to derail that discussion.
Rust allows this:
fn insert_str<'a>(map: &mut HashMap<&'a str, usize>, key: &'a str) {
map.insert(key, 0);
}
fn main() {
let mut map = HashMap::<&'static str, usize>::new();
let key = String::from("3");
insert_str(&mut map, &key);
}
I.e. the &'static str
in the turbofish was shortened to &'_ str
for the actual type. Playground.
Using type ascription on the binding itself does not:
// Lifetime error, as expected
let mut map: HashMap::<&'static str, usize> = HashMap::new();
The turbofish behaviour surprised me. In the process of writing this post, though, I believe I've come to understand it:
- Compiler sees
HashMap::<&'static str, usize>::new()
and resolves it to an implementation that does not involve an explicit'static
lifetime - The binding in turn does not have a
'static
bound - Nothing else requires a
'static
bound either - So the type of map has a resolution (which is not
'static
) and the program compiles
And nothing unintentional (language wise) is going on. Is this all correct? I guess this means turbofish has variance?