pyret-lang
pyret-lang copied to clipboard
Bad error message for wrong value passed to table filter
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)
(Creating issue so I don't lose it, that should be enough to reproduce, can get a better CPO screenshot to go with it.)
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-argerror with the right information in it: (this spy is at https://github.com/brownplt/pyret-lang/blob/horizon/src/arr/trove/contracts.arr#L100) - Note the
app-srcloccovers the entiret.filter(false)expression, and theastfield that comes back is ans-appofs-dot(<t>, "filter", ...)and an argument list of one argument. - Note the
failure-at-argcorrectly has an args with two items in it (the table, and false), and an index of 1 - But the
render-fancy-reasonmethod looks at theastfield that's been obtained by the app location, which ist.filter(false), and that's ans-appwith a one-elementargslist. And thengetting the 1th item from that 1-element list yields an index out of bounds error insidelist.get, which in turn bubbles out as a "One or more internal errors..." message. - In the meantime,
error-uitries to callrender-reasonas 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.