Compiler flag to show all errors

Can we please have a compiler flag to show all errors (I’m not referring to --error-trace) in a compact one line format each, along with obviously the total error count? I’ve a really large experimental codebase and I’m really tired of fixing one error at a time and I’m sure others will find it handy too! Please? Please?!

This is not as simple as adding a flag to enable multi error output. When the compiler encounters an error, it immediately stops. Because the program has already been proven to be invalid, there is not a known state from which to continue working. The compiler looks at the entire program as a whole, so there are no individual sub-units that could be considered separately.

However, we have recently iterated on some ideas to still allow the compiler to continue in a somewhat meaningful way by typing every broken piece as NoReturn and continue from that. This might work and help to identify lots of errors in the codebase. But so far there’s not even a PoC implementation of that, as a far as I know.

There’s also a new language in development called Roc where you have a way to make compile errors be runtime errors. Well, you get to see the whole list of compile errors, but it still produces a “valid” program that, when facing those code paths, will give a runtime error with that compile time error, if that makes sense.

I think it would be great to implement this for our compiler, but it’s a pretty big and challenging task.

To give some ideas for whoever decides to implement this…

Undefined constant

If you use an undefined constant, report a compile error but define the constant as a module and go on. For example:

puts FOO

Will give at compile time:

“Undefined constant FOO”

but will produce a program that, when you run it, outputs “FOO” (since FOO is defined as a module)

No method, or no overload matches

If you call a method that doesn’t exist, the compiler records the error and defines a method with the given types that raises on runtime with that same error:

class Foo
end

foo = Foo.new
foo.hello(1)

At compile-time you get:

"Undefined method hello for Foo"

but the compiler defines this method:

class Foo
  def hello(value : Int32)
    raise "Undefined method `hello` for `Foo`"
  end
end

and goes on.

Tricky part

The tricky part is when you assign a type to a variable that can’t hold that type:

class Foo
  property x = 0
end

foo = Foo.new
foo.x = "Hello"

I don’t know what can be done there… maybe the call should be replaced with something else that raises at runtime, or maybe these can’t produce a working binary.

1 Like

I don’t see the tricky thing in the tricky part. Isn’t Foo#x=(String) just an undefined method, like Foo#hello(Int32) in the example before?

Ah, yes. I guess it’s tricky if it’s an assignment directly to an instance var.

Thank you both! I suspected it wasn’t going to be easy and that Crystal probably stopped right after the first error. The problem I see with this approach is when working with a large codebase the actual effort involved to get to a working program stage cannot be estimated. When I sit down to code I normally find myself coding to get as many ideas out of my head as possible. Hopefully most of them work the way I want it to but given the slow compilation in Crystal I normally don’t wish to run the compiler after every change to save time. I really wish there was a way to add this to Crystal by considering sub-units perhaps at the class or file level?

There are no sub-units. The language doesn’t work like that. I understand what you want, and it’s what everyone wants and wanted for a long time, but there’s no actual way to do it.

1 Like

I normally write tests at this level specifically because Crystal doesn’t support this. One of the first things I do in any new Crystal project is remove the require "../src/#{project_name}" line from spec/spec_helper.cr so it doesn’t try to compile the whole project just so I can test one method in one class.

Keeping tests small and focused like that has helped me because I have a similar “brain-dump then organize” style of writing code. Maybe it could help you?

1 Like