HashMap struct key with `'static` lifetime screws with return lifetime using methods like `.get()`
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
I'm not sure what words to use to actually describe (or search for a dupe) this issue, so I'll just post it here and hope that it makes more sense to you guys (and sorry if it is a dupe; I'm almost sure it would be)!
So basically, if I write this code:
use std::collections::HashMap;
#[derive(PartialEq,Eq,Hash)]
struct Key<'a> {
key: &'a str
}
struct Foo {
types: HashMap<Key<'static>, String>,
}
impl Foo {
fn resolve<'this, 'a>(
&'this self,
key: &'a str,
) -> Option<&'this String> {
self.types.get(&Key { key })
}
}
I get back this error:
error: lifetime may not live long enough
--> src/lib.rs:17:9
|
13 | fn resolve<'this, 'a>(
| ----- -- lifetime `'a` defined here
| |
| lifetime `'this` defined here
...
17 | self.types.get(&Key { key })
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ method was supposed to return data with lifetime `'this` but it is returning data with lifetime `'a`
|
= help: consider adding the following bound: `'a: 'this`
Despite the fact that HashMap::get() returns the values with a lifetime of self, and nothing to do with the key provided.
However, this does work:
use std::collections::HashMap;
#[derive(PartialEq,Eq,Hash)]
struct Key<'a> {
key: &'a str
}
struct Foo {
types: HashMap<&'static str, String>,
}
impl Foo {
fn resolve<'this, 'a>(
&'this self,
key: &'a str,
) -> Option<&'this String> {
self.types.get(key)
}
}
Removing the struct indirection when defining the key type seems to make things happy!
Background
The above is a minimal reproduction of the issue I ran into, but the reason I ran into it is because I want to have something like:
use std::collections::HashMap;
struct Foo {
types: HashMap<(String,String), String>,
}
impl Foo {
fn resolve<'this, 'a>(
&'this self,
key1: &'a str,
key2: &'a str,
) -> Option<&'this String> {
self.types.get(&(key1, key2))
}
}
In other words, I want to be able to borrow more than 1 value to lookup some owned key in the hashmap. I went down the route of trying struct Key<'a> { a: Cow<'a,str>, b: Cow<'a,str> and then HashMap<Key<'static>, String>, but this led me to bumping up against this odd lifetime issue :)
Any pointers would be amazingly welcome!
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the minimal example in src/lib.rs, focusing on the HashMap::get call at line 17 and how the borrowed Key lifetime affects the returned value. Compare the behavior with the direct &'static str key example, then determine whether borrow checking or lifetime inference is incorrect and document a confirmed expected result with a regression test.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100