[GHC] #9173: Better type error messages

GHC ghc-devs at haskell.org
Mon Apr 30 14:21:20 UTC 2018


#9173: Better type error messages
-------------------------------------+-------------------------------------
        Reporter:  simonpj           |                Owner:  goldfire
            Type:  bug               |               Status:  new
        Priority:  high              |            Milestone:
       Component:  Compiler          |              Version:  7.8.2
      Resolution:                    |             Keywords:
                                     |  TypeErrorMessages
Operating System:  Unknown/Multiple  |         Architecture:
 Type of failure:  Incorrect         |  Unknown/Multiple
  warning at compile-time            |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by goldfire):

 I think the time is ripe for this ticket, and it shouldn't be hard. Here
 are the pieces:

 1. Update `TcErrors.mkExpectedActualMsg` to print out the `uo_thing` field
 of the `TypeEqOrigin` passed in. For example, if we're reporting an actual
 of `Maybe Int` and an expected of `Bool`, then `uo_thing` might hold `Just
 5`. This step can likely be done by changing `msg1` of
 `mkExpectedActualMsg`.

 2. Rip out the special treatment of kinds in `mkExpectedActualMsg`. Other
 than swapping out the word "kind" for "type", kinds and types should be
 treated the same. This special treatment is currently there solely to
 match pre-8.0 behavior. Doing this step should improve the error messages
 worsened by #14066 and fix, e.g., #14887. Concretely, this step is
 essentially to remove `msg5` from `mkExpectedActualMsg`.

 Those two steps, by themselves, would nail this ticket. But Simon and I
 think we can do better. Currently, the `uo_thing` of a `TypeEqOrigin`
 tracks the term (or type, during kind-checking) that has the "actual"
 type. (It's the `Just 5` mentioned in step 1.) However, we can also track
 the aspect of the context that leads us to expect the "expected" type. For
 example, this string could be something like "required as the condition of
 an `if`" or "of the second argument of `($)`" or "of the type used in a
 type signature". Here are example error messages:

 Code: `if 'x' then foo else bar`

 {{{
   Type mismatch: `Char' /= `Bool'
   Actual:   `Char' is the type of `'x''
   Expected: `Bool` is the type required as the condition of an `if'
 }}}

 Code: `not $ 'x'`

 {{{
   Type mismatch: `Char' /= `Bool'
   Actual:   `Char` is the type of `'x''
   Expected: `Bool` is the type of the second argument of ($)
 }}}

 Code: `foo :: Maybe`

 {{{
   Kind mismatch: `* -> *' /= `*'
   Actual:   `* -> *' is the kind of `Maybe'
   Expected: `*` is the kind of the type used in a type signature
 }}}

 Aren't these just lovely?

 To do this:

 3. Add an `SDoc` field to the `Check` constructor of an `ExpType` (in
 `TcType`). Then, in every `mkCheckExpType`, supply an appropriate message.
 Ideally, this message will not mention any types, because there will be no
 chance to zonk them later.

 4. Add a new field `uo_context` to `TypeEqOrigin` (of type `Maybe SDoc`)
 that will get the doc from the `Check`. This seems like it will happen in
 `TcUnify.tcSubTypeDS_NC_O`, but perhaps in other places, too. It's worth
 checking every place we make a `TypeEqOrigin`.

 5. Teach `TcErrors.mkExpectedActualMsg` to use this new info.

 We could do steps 1-2 separately from 3-5, but given the very large number
 of error messages one would have to sweep through to do so, it seems best
 to common these changes up.

-- 
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/9173#comment:30>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list