brownplt / pyret-lang

The Pyret language.
Other
1.06k stars 106 forks source link

Improve error message for bad args to operators #1704

Open jpolitz opened 9 months ago

jpolitz commented 9 months ago
fun insert<T>(e :: T, l :: List<T>)
  -> List<T>:
  cases (List) l:
    | empty => [list: e]
    | link(f, r) =>
      if e < f:
        link(e, l)
      else:
        link(f, insert(e, r))
      end
  end
end

fun isort<T>(l :: List<T>)
  -> List<T>:
  cases (List) l:
    | empty => empty
    | link(f, r) =>
      insert(f, isort(r))
  end
end

With TC on yields: The type checker rejected your program because it found a T but it expected a an object type.

I think we could do better here, and make the type that's synthesized have a little more explanation than “an object type”.

jpolitz commented 9 months ago

A pretty specific type is synthed (https://github.com/brownplt/pyret-lang/blob/f1103c90388a6de3d3468ea48e67bf527f568d36/src/arr/compiler/type-check.arr#L1568), so the issue must be that in constraint solving the related error just gets called “an object type” – harder to track down; that string constant appears in a few places.

blerner commented 9 months ago

Isn't it just failing on "T isn't an object", and never getting to the field-level constraints?

jpolitz commented 9 months ago

Right, I think that's what I was saying – in constraint solving, it fails on “is type variable T an object type” and gives an error with that constant string.

One idea is to, when we see “S is not object” (for any type S), we search the constraint set for field constraints and report those.

That or augment whatever obj-exists is with more information to report in constraints, even up to something that says, effectively “This one was created as a constraint for lessthan” and use that to augment the error on failure.