Skip to content

[#886] Make missing Generic errors more readable

Nikolay Yakimov requested to merge lierdakil/#886-readable-generic-errors into master

Note: if this approach is deemed acceptable, ToT may benefit from the same treatment, as a missing IsoValue instance can lead to very unwieldy error messages involving ToT.

Description

Problem: oftentimes when a Generic instance is missing for some type, we get arcane error messages mentioning something with GHC.Generics.Rep didn't match something else. This is especially exacerbated by custom type errors for scopes &c, which overlap any no instance Generic errors even if there are any.

Solution: Introduce closed type family GRep, which is itself stuck for ambiguous types, but for non-ambiguous types it checks whether Rep is stuck and displays an error message about missing Generic instance instead.

In some cases, type inference needs a little help (specifically when using GRep with Generic methods in a polymorphic context). Thus, introduce NiceGeneric constraint, which is Generic, but also asserts GRep is Rep.

Alternative design is to use an utility constraint and attach it everywhere Rep is used, but it's easy to miss an edge case, plus the constraint would be redundant, which would necessitate additional trickery.

Downsides of the current approcach:

  • When a type is ambiguous, the user may see a somewhat arcane error message along the lines of "can not match GRep a with Rep a, a is ambiguous". But there is enough information in this error message, namely that "a is ambiguous".

  • Due to the quirk of how custom type errors are handled, users may see the same "missing Generic instance" error multiple times (depending on how many times GHC substitutes GRep before giving up). This is slightly annoying, but bearable, in my testing, usually it's duplicated twice or thrice.

Related issue(s)

Resolves #886 (closed) (arguably)

Checklist for your Merge Request

Related changes (conditional)

  • Tests (see short guidelines)

    • If I added new functionality, I added tests covering it.
    • If I fixed a bug, I added a regression test to prevent the bug from silently reappearing again.
  • Documentation

    • I checked whether I should update the docs and did so if necessary:
    • I updated changelog files of all affected packages released to Hackage if my changes are externally visible.

Stylistic guide (mandatory)

Edited by Nikolay Yakimov

Merge request reports