pyret-lang icon indicating copy to clipboard operation
pyret-lang copied to clipboard

Bad error message for wrong value passed to table filter

Open jpolitz opened this issue 3 years ago • 2 comments

It came from entering animals-table.build-column("is-dog",is-dog).filter(is-dog == true) instead of animals-table.build-column("is-dog",is-dog).filter(is-dog)

jpolitz avatar Aug 31 '22 01:08 jpolitz

(Creating issue so I don't lose it, that should be enough to reproduce, can get a better CPO screenshot to go with it.)

jpolitz avatar Aug 31 '22 01:08 jpolitz

A smaller repro:

t = table: name row: "Sasha" end
t.filter(false)

The internal error does not reproduce at the command-line; it seems to have to do with an index-out-of-bounds error in list.get, as used by failure-at-arg's render-fancy-reason method.

And the cause of the internal error turns out to be quite gnarly! I added some spy blocks to figure out what's going on, and I think it's:

  • We create a failure-at-arg error with the right information in it: (this spy is at https://github.com/brownplt/pyret-lang/blob/horizon/src/arr/trove/contracts.arr#L100) image
  • Note the app-srcloc covers the entire t.filter(false) expression, and the ast field that comes back is an s-app of s-dot(<t>, "filter", ...) and an argument list of one argument.
  • Note the failure-at-arg correctly has an args with two items in it (the table, and false), and an index of 1
  • But the render-fancy-reason method looks at the ast field that's been obtained by the app location, which is t.filter(false), and that's an s-app with a one-element args list. And then getting the 1th item from that 1-element list yields an index out of bounds error inside list.get, which in turn bubbles out as a "One or more internal errors..." message.
  • In the meantime, error-ui tries to call render-reason as a fallback, which succeeds (since it's not trying to produce the exact argument out of the args list), but it produces a weird message too, blaming argument 2.

I don't know what the right fix here is. This is a nasty interaction of our stack-to-ast-lookup heuristics, and even if we said "Check whether maybe-astreturns asome(ast), and ast.args.length()is greater thanself.index, before trying to get` that argument", but that still leaves the possibility that the argument is off by one index because we aren't tracking method calls vs function calls properly.

blerner avatar May 02 '24 02:05 blerner