Improve error messages for record updates that don't typecheck
We now typecheck record updates by desugaring the record update to a case expression (MR !7981 (merged)). However, this can mean some of the error messages aren't particularly clear about the source of the error.
Example 1
{-# LANGUAGE GADTs #-}
data E where
MkE :: Show e => { ex :: e } -> E
ex_upd r = r { ex = undefined }
* Could not deduce (Show e0)
from the context: Show e
bound by a pattern with constructor:
MkE :: forall e. Show e => e -> E,
in a case alternative
at testsuite\tests\typecheck\should_fail\T3323b.hs:11:12-31
The type variable `e0' is ambiguous
Potentially matching instances:
instance Show Ordering -- Defined in `GHC.Show'
instance Show a => Show (Maybe a) -- Defined in `GHC.Show'
...plus 25 others
...plus 12 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
* In a record update at field `ex',
with type constructor `E',
data constructor `MkE'
and existential variable `e'.
Example 2
{-# LANGUAGE TypeFamilies #-}
type family F a
data D a b =
MkD { fld1 :: a -> b
, fld2 :: F a -> F b }
d :: D z z
d = MkD { fld1 = id, fld2 = id }
foo _ = d { fld1 = id }
* Could not deduce (F z0 ~ F b)
from the context: F z ~ F b
bound by the inferred type for `foo':
forall {z} {b} {p}. (F z ~ F b) => p -> D b b
at testsuite\tests\typecheck\should_fail\T3323b.hs:15:1-23
NB: `F' is a non-injective type family
The type variable `z0' is ambiguous
* In the ambiguity check for the inferred type for `foo'
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
When checking the inferred type
foo :: forall {z} {b} {p}. (F z ~ F b) => p -> D b b
|
15 | foo _ = d { fld1 = id }
| ^^^^^^^^^^^^^^^^^^^^^^^
This error message doesn't even mention anything about a record update, which isn't great.
Ideas
One difficulty with reporting good error messages in this area is that we'd like to tag the generated code as having a certain origin, so that constraints emitted when typechecking the generated code would be tagged with "In the record update...". This would also allow better error messages, as CtOrigins are reported after constraint solving, so we can print the actual types that caused an issue, rather than using addErrCtxt where we have to provide the full message then-and-there.