-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Type mismatch error should have spans if it's too long #21025
Comments
cc me |
I think there may already be an issue on this (@wycats, do you remember?), but I think another approach here is to change the formatting so that the expected/found types are on separate lines, aligned horizontally, with diffs (identified textually) highlighted in red. This would be fantastic to implement but probably requires a richer alternative to |
Something like |
Big +1. This would be a killer feature and one that every beginner would soon be aware of :) |
We frequently run into problems like these. Thankfully we have already seen some significant improvements, primarily that errors like this are now split up into several lines, and that Rust actually tries (with varying success) to point out where it happened. For example, the error mentioned by @Manishearth now looks like this:
Which is already much better. For us, it would be immensely helpful, if a lot of the superfluous stuff was removed from the "found" part of the error message. The "expected" part is nicely trimmed, with underscores replacing irrelevant type parameters. Ideally, the error message would look something like:
(With or without the |
Or, to put it more simply, consider the following code struct Foo<T, U> ( u8 );
fn bar(x: Foo<u8, i8>) {
}
fn main() {
let x: Foo<u8, u8> = Foo(42);
bar(x);
} We get the following error message: foo.rs:9:7: 9:8 error: mismatched types:
expected `Foo<u8, i8>`,
found `Foo<u8, i64>`
(expected i8,
found i64)
foo.rs:9 bar(x);
^
error: aborting due to previous error Ideally, Rust could replace |
Another case:
would be much easier to read if (a) it factored out the common type and (b) suggested a fix:
|
Triage; still lots of room for improvement here. |
I can see five possible cases:
For the 1st case, I like @dhardy's proposal:
For the 2nd case, I can't think of a nice way to present it over what we already have: the types are simply wrong. For the 3rd case it currently would look a bit like this, which I don't think is too bad:
but could be changed to look this way to look consistent with the 1st case's (this example is for the 4th case, but it'd look practically the same for the 3rd case):
Supporting this case could get hairy quickly. For example, how many type parameters before you are noisier than the current message? The 5th case is the same as the 1st one, only reversed:
The way I see it, there's nothing that could be done for the 2nd case, supporting the 4th could be tricky to get right, and the 3rd case is already somewhat clean. That leaves case 1 and 5 as the most highly actionable messages to work on (finding if there're sub matches on type inequality), with the possibility to clean up the 3rd case slightly as asked by @Munksgaard (replace types parameters that are are equal with underscore on message). Does that look right? |
…, r=nikomatsakis Highlight and simplify mismatched types Shorten mismatched types errors by replacing subtypes that are not different with `_`, and highlighting only the subtypes that are different. Given a file ```rust struct X<T1, T2> { x: T1, y: T2, } fn foo() -> X<X<String, String>, String> { X { x: X {x: "".to_string(), y: 2}, y: "".to_string()} } fn bar() -> Option<String> { "".to_string() } ``` provide the following output ```rust error[E0308]: mismatched types --> file.rs:6:5 | 6 | X { x: X {x: "".to_string(), y: 2}, y: "".to_string()} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `std::string::String`, found {integer} | = note: expected type `X<X<_, std::string::String>, _>` ^^^^^^^^^^^^^^^^^^^ // < highlighted found type `X<X<_, {integer}>, _>` ^^^^^^^^^ // < highlighted error[E0308]: mismatched types --> file.rs:6:5 | 10 | "".to_string() | ^^^^^^^^^^^^^^ expected struct `std::option::Option`, found `std::string::String` | = note: expected type `Option<std::string::String>` ^^^^^^^ ^ // < highlighted found type `std::string::String` ``` Fix rust-lang#21025. Re: rust-lang#40186. Follow up to rust-lang#39906. I'm looking to change how this output is accomplished so that it doesn't create list of strings to pass around, but rather add an elided `Ty` placeholder, and use the same string formatting for normal types. I'll be doing that soonish. r? @nikomatsakis
It would be useful if there was a note as to where the
()
andString
from(expected (), found struct collections::string::String)
were for large types.An additional note that's shown when the error report is above x (300?) characters which highlights the mismatched types (using something like our
^~~~~~
for code spans) would be useful.The text was updated successfully, but these errors were encountered: