Skip to content

[#733][#658] Extract actual + expected pattern into a datatype and show diff in type mismatch

Nikolay Yakimov requested to merge lierdakil/#658-diff-type-mismatch into master

Description

This MR addresses two issues, which are just too convenient to handle togehter.

Problem 1: Errors (particularly mismatch errors) often tend to carry actual + expected values, but handling this is not very convenient.

Solution 1: Add a dedicated MismatchError record datatype.

  • Replace EPExpected and EPActual added in !975 (merged) with MismatchError
  • Use MismatchError in
    • UnexpectedTopLevelType
    • UnexpectedStorageType, UnexpectedBigMapKeyType, UnexpectedBigMapValueType
    • VIMViewArgMismatch, VIMViewRetMismatch
    • TypeEqError
    • EEUnexpectedParameterType

TODO:

  • Should also be possible to use this with StackEqError, but a little more complicated due to mismatch in stacks, need some additional trickery to present a pretty diff for a list of types.

Problem 2: With type errors in large types, it's hard to find the difference at a glance, which wastes a non-negligible amount of time.

Solution 2: Show a diff-style mismatch report on MismatchErrors for Untyped.Ty and Typed.T. The diff is produced by printing the types in a multiline format, then computing the line diff with the standard algorithm (as implemented by the Diff package).

Alternative approaches that were explored and rejected:

  • Compare type trees using generics. Comparison itself works quite well, the issue is it's impossible to represent the result of such comparisson so that it can be pretty-printed: unless we're willing to reimplement the whole RenderDoc logic by matching on generic metadata, which ultimately seems a bit too brittle and tedious.

  • Recover the base functor of Untyped.T and build a recursive binary tree for local mismatches on top of that via Data.Fix.This would let us represent the mismatch as a branch in the extended type AST. Unfortunately, writing all this out by hand bascally duplicates most of the declarations from Untyped. Additionally, recursion-schemes, which could save us a lot of tedious duplication, doesn't handle indirect recursion (which we have via Ty -> T -> Ty).

Related issue(s)

Resolves #733 (closed), resolves #658 (closed).

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