I wanted together a quick post talking about an idea I was brainstorming with @brson and @nikomatsakis last week.
Background
For a type mismatch error, there often are a known set of steps to transition from one type to another. If it’s the first time the user has seen this error, they’re forced to go read docs to find the correct API call to do the conversion. This takes time and can be a bit frustration. Luckily, over time your muscle memory will kick in with the known conversion (eg String->&str or &str->String) and it will then just be a minor inconvenience to do the fix.
Improved errors
The idea is pretty simple: have the compiler search the methods on the type looking for a compatible self parameter as the one argument and the expected type as the return type.
For the &str
to String
case, for example, it may find:
fn to_string(&self) -> String
This can then become a suggestion we give the user. Whereas currently we say:
error[E0308]: mismatched types
--> <anon>:4:17
|
4 | expect_string("foo");
| ^^^^^ expected struct `std::string::String`, found reference
|
= note: expected type `std::string::String`
= note: found type `&'static str`
We could potentially say:
error[E0308]: mismatched types
--> <anon>:4:17
|
4 | expect_string("foo");
| ^^^^^ expected struct `std::string::String`, found reference
|
suggestion:
| expect_string("foo".to_string());
| ------------ convert to a String
Caveats
Can’t grab methods blindly
If we search for this pattern naively, we could potentially suggest methods that have side effects. While, yes, the correct type comes out, the dev could have inadvertently added a difficult to debug issue to their code in the process, just because the compiler told them to.
To prevent this, we may need to annotate methods with a “safe for suggestion” keyword that the suggestion logic can understand.
Multiple steps needed
Sometimes it’s more than just one step. While we don’t necessarily want to search deeply, we could do a limited number of steps. Assuming something like the “safe for suggestion” feature above, we’re in a small, bounded search space and still able to deliver helpful suggestions.
Supporting &
and &mut
Since adding an &
or &mut
is a common task in Rust, we should also add them to the search space for each step (assuming the type is allowed to take that step)
Multiple possibilities
Sometimes there are multiple possibilities for the conversion. It may be through one step (like .to_string()
and .into()
) or different ways to multi-step to the right type. We’d need to come up with a heuristic here, eg) possibly showing a couple suggestions sorted by the by the shortest in terms of character length.
How do generics/traits factor into this?
I have no idea This may be easier than it seems, I’m not sure. If it proves to be tricky, maybe we can support them in a later revision of the idea as we get more experience with it?