Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Compiler says to add type parameters, but I don't think I can in this context

The compiler complains that type annotations are needed. I was able to fix it by creating an unused variable with type parameters, commented out in the code snippet below. This feels like a weird workaround though, is there some way to add type parameters without needing to do this? It just seems like rust should know the type of key because Map is a defined type.

type Map = Arc<DashMap<[u8; 32], Session>>;

pub struct SessionManager {
    map: Map,
    db_wtx: WriteTx,
    db_rtx: ReadTx,
}

impl SessionManager{
    pub fn logout(&self, token: &str) {
        if let Ok(decoded_vec) = base64::decode(token) {
            if let Ok(key) = decoded_vec.try_into() {
                //let _typed_key: [u8; 32] = key;
                self.map.remove(&key);
            }
        }
    }
}

Error msg:

error[E0282]: type annotations needed
   --> src/login_handler.rs:244:14
    |
244 |             if let Ok(key) = decoded_vec.try_into() {
    |                       ^^^    ---------------------- this method call resolves to `Result<T, <Self as TryInto<T>>::Error>`
    |                       |
    |                       cannot infer type

edit: for clarity I’m using the dashmap crate, which tries to mimic the api of std::hashmap closely while allowing multithreaded access.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

rustc can’t infer the type because Map::remove() (assuming you’re actually talking about HashMap, or BTreeMap) doesn’t take &K as the parameter type (where K is the key type), but rather some Q where Q: Borrow<K>. This allows for more flexibility (for example, passing a &str for a map of Strings), but come at the cost of worse inference.

There are few alternatives: You can specify the type for the Ok:

if let Ok::<[u8; 32], _>(key) = decoded_vec.try_into()

This is a shorthand for:

if let Result::<[u8; 32], _>::Ok(key) = decoded_vec.try_into()

Or you can use TryFrom instead of TryInto:

if let Ok(key) = <[u8; 32]>::try_from(decoded_vec)

If you choose a variable, note that it is preferred to use _ and not another underscore-prefixed name like _typed_key. This is because _ does not move the value, but any other name does. This does not relevant in this case since [u8; 32] is Copy, but still a good practice.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading