Skip to content

Verbose type names can make error messages difficult to read #12401

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

Open
Jarred-Sumner opened this issue Aug 11, 2022 · 3 comments
Open

Verbose type names can make error messages difficult to read #12401

Jarred-Sumner opened this issue Aug 11, 2022 · 3 comments
Labels
enhancement Solving this issue will likely involve adding new logic or components to the codebase. error message This issue points out an error message that is unhelpful and should be improved.
Milestone

Comments

@Jarred-Sumner
Copy link
Contributor

A type error within a function that has the following signature:

        pub fn printAs(
            this: *ZigConsoleClient.Formatter,
            comptime Format: ZigConsoleClient.Formatter.Tag,
            comptime Writer: type,
            writer_: Writer,
            value: JSValue,
            jsType: JSValue.JSType,
            comptime enable_ansi_colors: bool,
        ) void {
            var writer = WrappedWriter(Writer){ .ctx = writer_ };

Produces an error message like this:
image

The expected type name is:

std.io.writer.Writer(*std.io.buffered_writer.BufferedWriter(4096,std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)),std.os.WriteError,std.io.buffered_writer.BufferedWriter(4096,std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)).write)

I don't have a specific solution in mind

@Vexu Vexu added enhancement Solving this issue will likely involve adding new logic or components to the codebase. error message This issue points out an error message that is unhelpful and should be improved. labels Aug 11, 2022
@Vexu Vexu added this to the 0.12.0 milestone Aug 11, 2022
@wooster0
Copy link
Contributor

wooster0 commented Aug 11, 2022

Here's another example that showcases it well:

const std = @import("std");

pub fn main() void {
    var x = std.io.countingWriter(std.io.countingWriter(std.io.getStdOut().writer()));
    y(x);
}

fn y(x: @TypeOf(std.io.countingWriter(std.io.bufferedWriter(std.io.getStdOut().writer())))) void {
    _ = x;
}
./x.zig:10:7: error: expected type 'std.io.counting_writer.CountingWriter(std.io.buffered_writer.BufferedWriter(4096,std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)))', found 'std.io.counting_writer.CountingWriter(std.io.counting_writer.CountingWriter(std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)))'
    y(x);
      ^
/zig-linux-x86_64/lib/std/io/counting_writer.zig:7:12: note: std.io.counting_writer.CountingWriter(std.io.buffered_writer.BufferedWriter(4096,std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write))) declared here
    return struct {
           ^
/zig-linux-x86_64/lib/std/io/counting_writer.zig:7:12: note: std.io.counting_writer.CountingWriter(std.io.counting_writer.CountingWriter(std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write))) declared here
    return struct {
           ^

Try reading that in a terminal and spot the difference. It's really hard.
For me it looked like this in the terminal:

./x.zig:10:7: error: expected type 'std.io.counting_writer.CountingWriter(std.io.buffered_writer.BufferedWriter(4096,std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)))', found 'std.i
o.counting_writer.CountingWriter(std.io.counting_writer.CountingWriter(std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)))'

So the issue here is that there's a type mismatch and it shows you the two types it has and the developer wants to know what's different between those two types and spot the difference.
One thing that really helps if you want to compare two things is if you have to them below each other in 2 lines:

./x.zig:10:7: error: expected type 'std.io.counting_writer.CountingWriter(std.io.buffered_writer.BufferedWriter(4096,std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)))',
                     found type    'std.io.counting_writer.CountingWriter(std.io.counting_writer.CountingWriter(std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)))'

With this alignment the difference is already a lot easier to spot.

However with too small window sizes and too long types it will still cut off and we will have the same problem.
We could use a diff algorithm for that, but I'm not entirely sure how this would look.
Instead of making this too complicated, let's just highlight the different characters with a different color in the terminal.
So in the example above it would highlight the second line starting at counting_writer.

Apart from that, we could try shortening the type names. One thing we could try is to limit the nesting when it's no longer important to see the other things inside the parentheses? Maybe like this (notice the ellipses at the end)?

./x.zig:10:7: error: expected type 'std.io.counting_writer.CountingWriter(std.io.buffered_writer.BufferedWriter(...))',
                     found type    'std.io.counting_writer.CountingWriter(std.io.counting_writer.CountingWriter(...))'

This should give the dev enough info right? I don't know how viable this is though so someone else would have to say.

@wooster0
Copy link
Contributor

And I wonder where else we have such cases where there's a mismatch and you're shown two things and you have to spot the difference. Maybe we can generalize the solution then.

@tauoverpi
Copy link
Contributor

It would be nice if zig could point to where they differ given that types should now (iirc) all have a normalized name. Thus the above:

./x.zig:10:7: error: expected type 'std.io.counting_writer.CountingWriter(std.io.buffered_writer.BufferedWriter(4096,std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)))', found 'std.io.counting_writer.CountingWriter(std.io.counting_writer.CountingWriter(std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)))'
    y(x);
      ^

becomes:

./x.zig:10:7: error: expected type 'std.io.counting_writer.CountingWriter(std.io.buffered_writer.BufferedWriter(4096,std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)))', found 'std.io.counting_writer.CountingWriter(std.io.counting_writer.CountingWriter(std.io.writer.Writer(std.fs.file.File,std.os.WriteError,std.fs.file.File.write)))'
    y(x);
      ^
  where
      std.io.counting_writer.CountingWriter(...)
    is not equivalent to
      std.io.buffered_writer.BufferedWriter(...)
    in
      std.io.counting_writer.CountingWriter(...)

where the in section would show from the root up to the point it differs while where and is not equivalent to show where the types start to differ.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Solving this issue will likely involve adding new logic or components to the codebase. error message This issue points out an error message that is unhelpful and should be improved.
Projects
None yet
Development

No branches or pull requests

4 participants