In my opinion, this behavior of Rust’s type inference is confusing, so with some luck, maybe eventually it could change. In the case of your specific example, you might want to choose an Into-based bound anyways, since that’s generally recommended anyways (Into docs containing quote below)
Prefer using Into over From when specifying trait bounds on a generic function to ensure that types that only implement Into can be used as well.
So then the code becomes
fn test<T>(arg_t: T)
where
T: Into<String>
{
let _a: String = arg_t.into();
let _c = String::from("TEST");
}
Since this is only a problem with type inference, the original code can also be fixed by being more explicit about the trait that’s used:
fn test<T>(arg_t: T)
where
String: std::convert::From<T>,
{
let _a = String::from(arg_t);
let _c = <String as From<&str>>::from("TEST");
}
or you can use a different method of &str to String conversion, e.g.
fn test<T>(arg_t: T)
where
String: std::convert::From<T>,
{
let _a = String::from(arg_t);
let _c = "TEST".to_owned();
}
or
fn test<T>(arg_t: T)
where
String: std::convert::From<T>,
{
let _a = String::from(arg_t);
let _c: String = "TEST".into();
}
or
fn test<T>(arg_t: T)
where
String: std::convert::From<T>,
{
let _a = String::from(arg_t);
let _c = "TEST".to_string();
}
Looks like it, indeed. I encountered this behavior, and although I was able to work around it, I wanted to understand it. Anyway, thanks for the answer.
I'll try switching to the Into trait, thanks for the tip.