acton icon indicating copy to clipboard operation
acton copied to clipboard

Compiler should print error messages in top down order as encountered in a file

Open bdolenc opened this issue 9 months ago • 4 comments

If you have multiple bugs in your acton module they are produced in reversed order, starting at the bottom of the file:

class Circle():
    radius: float

    def __init__(self, radius):
        self.radius = radius


actor main(env):
    shape = Circle(3.14)
    print(shape.radius)
    # accessing attribute that does not exist
    print(shape.area)
    # another one
    print(shape.size)
    env.exit(0)

Compiler starts complaining at the bottom with shape.size:

  Compiling compiler_error_order.act for release
[error]: Attribute not found size
     ╭──▶ compiler_error_order.act@14:17-14:21
     │
  14 │     print(shape.size)
     •                 ┬───
     •                 ╰╸ Attribute not found size

OTOH it seems that some errors do end up before others:

actor main(env):
    # Wrong init
    shape = Circle(3.14, 5)
    print(shape.radius)
    # accessing attribute that does not exist
    print(shape.area)
    # another one
    print(shape.size)
    env.exit(0)

This results in wrong init error being thrown first:

  Compiling compiler_error_order.act for release
[error]: Incompatible types
     ╭──▶ compiler_error_order.act@9:13-9:28
     │
   9 │     shape = Circle(3.14, 5)
     •             ┬──────────────
     •             ╰╸ too many positional component(s) in tuple

It would be best if errors would pop up in order that they are encountered in the module, from top to bottom - this makes it easier to debug. Otherwise you can be deceived that code before hand is correct and the same pattern somehow doesn't work further down the file while it is actually wrong too and compiler just started showing errors at the bottom.

bdolenc avatar Mar 19 '25 07:03 bdolenc

@nordlander what is the reason for this? Is it a simple Haskell cons thing or do we fundamentally walk through things in a reverse order for a good reason?

plajjan avatar Mar 19 '25 08:03 plajjan

It's actually a bit trickier: the type constraints that are collected from the source code are first sorted into non-overlapping groups, then solved in order of increasing weight (where weight basically means the number of potential solutions that might have to be tried). So it would be pretty hard to guarantee that type errors are reported in source code order given this implementation.

That said, I'm sure there are cases where weights are actually equal and the compiler currently just picks the constraint that happens to be first in some internal list. Here we could probably do better, by being more careful about the order in which we construct such lists. I'm making this a requirement for my upcoming overhaul of the constraint solver!

nordlander avatar Mar 19 '25 09:03 nordlander

I don't think we are necessarily looking for a strict guarantee on order-in-source but rather, when possible, it would be desirable to roughly use the order of the source file.

I don't think we should go to any extreme lengths to redesign how error reporting is done from non-overlapping groups of constraints to exactly reflect order-in-source but if we can get some rough approximation with simple means, let's go for it.

plajjan avatar Apr 01 '25 09:04 plajjan

I have been doing some test shots at handling failures during parsing, which essentially means we don't stop parsing when we encounter an error but instead represent it with an Error node and attempt to recover and continue parsing. We talked about this in one of the weekly calls to which @nordlander commented that all passes should accept partial / broken input and do the best job possible. Besides adding an Error node to the AST, we also write a list of the errors we encounter.

This issue is about ordering of error message when they pop up, one at a time, where the compiler immediately exits upon the first encountered error. If we accumulate errors then we can instead present all or at least many errors in one go. I think the ordering is then much easier to handle as we can talk about order as per source code rather than order-of-encountered-error-which-immediately-exits. Every error has a "main" part to which it points (in addition to additional pointers for references) - if we just sort those according to source code line for displaying to the user, I think we'll get something very natural looking!

I opened #2371 for the general error recovery.

@nordlander WDYT, will you attempt to raise the current immediate errors in some specific order to reflect source-code-order or do you think we should just aim for the general error recovering case -> get list of all errors -> sort ?

plajjan avatar Jul 18 '25 08:07 plajjan