Description
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.