Skip to content

Type inference problem #95358

Open
Open
@jongiddy

Description

@jongiddy

I originally posted this at https://users.rust-lang.org/t/type-inference-failure-in-simple-generic-method-call/73423 but didn't get much response, apart from agreement that this is weird.

This code wraps the reqwest::ReqwestBuilder::header<K, V> method with a function that has the same signature. Both functions have generic parameters K and V that should be easily and independently inferred from the types passed to each function.

fn set_sensitive_header<K, V>(
    builder: reqwest::RequestBuilder,
    key: K,
    value: V,
) -> reqwest::RequestBuilder
where
    http::header::HeaderName: TryFrom<K>,
    <http::header::HeaderName as TryFrom<K>>::Error: Into<http::Error>,
    http::HeaderValue: TryFrom<V>,
    <http::HeaderValue as TryFrom<V>>::Error: Into<http::Error>,
    V: Copy
{
    match http::HeaderValue::try_from(value) {
        Ok(mut header_value) => {
            header_value.set_sensitive(true);
            builder.header(key, header_value)
            // builder.header::<K, http::HeaderValue>(key, header_value)
        }
        Err(_) => builder.header(key, value),
    }
}

This fails with:

error[E0308]: mismatched types
  --> src/lib.rs:16:33
   |
1  | fn set_sensitive_header<K, V>(
   |                            - this type parameter
...
16 |             builder.header(key, header_value)
   |                                 ^^^^^^^^^^^^ expected type parameter `V`, found struct `HeaderValue`
   |
   = note: expected type parameter `V`
                      found struct `HeaderValue`

Adding the turbofish, as in the commented-out line, fixes the problem.

The generic types K and V on the header method should be trivially inferred from the supplied parameters. So this seems like a failure in type inference.

I thought this might be related to the where clauses constraining the concrete HeaderValue type, but changes like using TryFrom<V> + From<HeaderValue> did not fix it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions